[{"data":1,"prerenderedAt":4261},["ShallowReactive",2],{"navigation":3,"api-navigation":184,"\u002Flearn\u002Ftutorials\u002Ftasks-and-app-loop":206,"docyard:crossref-index":4260},[4,8,155,174,180],{"title":5,"path":6,"stem":7},"Getting Started","\u002Fgetting-started","1.getting-started",{"title":9,"path":10,"stem":11,"children":12},"Learn","\u002Flearn","2.learn",[13,15,66,99,133],{"title":9,"path":10,"stem":14},"2.learn\u002Findex",{"title":16,"path":17,"stem":18,"children":19},"Tutorials","\u002Flearn\u002Ftutorials","2.learn\u002F1.tutorials\u002Findex",[20,21,26,30,34,38,42,46,50,54,58,62],{"title":16,"path":17,"stem":18},{"title":22,"path":23,"stem":24,"icon":25},"Why Laco?","\u002Flearn\u002Ftutorials\u002Fwhy-laco","2.learn\u002F1.tutorials\u002F01.why-laco","i-lucide-notebook",{"title":27,"path":28,"stem":29,"icon":25},"First Steps with Laco","\u002Flearn\u002Ftutorials\u002Ffirst-steps","2.learn\u002F1.tutorials\u002F02.first-steps",{"title":31,"path":32,"stem":33,"icon":25},"Lazy Call and Partial","\u002Flearn\u002Ftutorials\u002Flazy-call-and-partial","2.learn\u002F1.tutorials\u002F03.lazy-call-and-partial",{"title":35,"path":36,"stem":37,"icon":25},"Hyperparameters and Interpolation","\u002Flearn\u002Ftutorials\u002Fhyperparameters-and-interpolation","2.learn\u002F1.tutorials\u002F04.hyperparameters-and-interpolation",{"title":39,"path":40,"stem":41,"icon":25},"Loading, Saving, and the CLI","\u002Flearn\u002Ftutorials\u002Floading-saving-cli","2.learn\u002F1.tutorials\u002F05.loading-saving-cli",{"title":43,"path":44,"stem":45,"icon":25},"Nested Configs and Containers","\u002Flearn\u002Ftutorials\u002Fnested-configs-and-containers","2.learn\u002F1.tutorials\u002F06.nested-configs-and-containers",{"title":47,"path":48,"stem":49,"icon":25},"Typed Groups and Schemas","\u002Flearn\u002Ftutorials\u002Ftyped-groups-and-schemas","2.learn\u002F1.tutorials\u002F07.typed-groups-and-schemas",{"title":51,"path":52,"stem":53,"icon":25},"Pipeline Configs","\u002Flearn\u002Ftutorials\u002Fpipeline-configs","2.learn\u002F1.tutorials\u002F08.pipeline-configs",{"title":55,"path":56,"stem":57,"icon":25},"Tasks and the App Loop","\u002Flearn\u002Ftutorials\u002Ftasks-and-app-loop","2.learn\u002F1.tutorials\u002F09.tasks-and-app-loop",{"title":59,"path":60,"stem":61,"icon":25},"Tracing","\u002Flearn\u002Ftutorials\u002Ftracing","2.learn\u002F1.tutorials\u002F10.tracing",{"title":63,"path":64,"stem":65,"icon":25},"Production Patterns","\u002Flearn\u002Ftutorials\u002Fproduction-patterns","2.learn\u002F1.tutorials\u002F11.production-patterns",{"title":67,"path":68,"stem":69,"children":70},"Concepts","\u002Flearn\u002Fconcepts","2.learn\u002F2.concepts\u002Findex",[71,72,76,80,84,88,92,95],{"title":67,"path":68,"stem":69},{"title":73,"path":74,"stem":75},"Config as Python","\u002Flearn\u002Fconcepts\u002Fconfig-as-python","2.learn\u002F2.concepts\u002F1.config-as-python",{"title":77,"path":78,"stem":79},"Lazy Construction","\u002Flearn\u002Fconcepts\u002Flazy-construction","2.learn\u002F2.concepts\u002F2.lazy-construction",{"title":81,"path":82,"stem":83},"Lie-Typing","\u002Flearn\u002Fconcepts\u002Flie-typing","2.learn\u002F2.concepts\u002F3.lie-typing",{"title":85,"path":86,"stem":87},"Interpolation","\u002Flearn\u002Fconcepts\u002Finterpolation","2.learn\u002F2.concepts\u002F4.interpolation",{"title":89,"path":90,"stem":91},"Typed Groups","\u002Flearn\u002Fconcepts\u002Ftyped-groups","2.learn\u002F2.concepts\u002F5.typed-groups",{"title":59,"path":93,"stem":94},"\u002Flearn\u002Fconcepts\u002Ftracing","2.learn\u002F2.concepts\u002F6.tracing",{"title":96,"path":97,"stem":98},"App Loop","\u002Flearn\u002Fconcepts\u002Fapp-loop","2.learn\u002F2.concepts\u002F7.app-loop",{"title":100,"path":101,"stem":102,"children":103},"How-To Guides","\u002Flearn\u002Fhow-to","2.learn\u002F3.how-to\u002Findex",[104,105,109,113,117,121,125,129],{"title":100,"path":101,"stem":102},{"title":106,"path":107,"stem":108},"Override Configs","\u002Flearn\u002Fhow-to\u002Foverride-configs","2.learn\u002F3.how-to\u002F1.override-configs",{"title":110,"path":111,"stem":112},"Safe Loading","\u002Flearn\u002Fhow-to\u002Fsafe-loading","2.learn\u002F3.how-to\u002F2.safe-loading",{"title":114,"path":115,"stem":116},"Custom Resolvers","\u002Flearn\u002Fhow-to\u002Fcustom-resolvers","2.learn\u002F3.how-to\u002F3.custom-resolvers",{"title":118,"path":119,"stem":120},"Lint and Strict Mode","\u002Flearn\u002Fhow-to\u002Flint-and-strict","2.learn\u002F3.how-to\u002F4.lint-and-strict",{"title":122,"path":123,"stem":124},"Publishing a reproducible app with laco app","\u002Flearn\u002Fhow-to\u002Flaco-app","2.learn\u002F3.how-to\u002F5.laco-app",{"title":126,"path":127,"stem":128},"Reproduce an Experiment","\u002Flearn\u002Fhow-to\u002Freproduce-experiment","2.learn\u002F3.how-to\u002F6.reproduce-experiment",{"title":130,"path":131,"stem":132},"Migrate from argparse","\u002Flearn\u002Fhow-to\u002Fmigrate-from-argparse","2.learn\u002F3.how-to\u002F7.migrate-from-argparse",{"title":134,"path":135,"stem":136,"children":137},"Examples Curriculum","\u002Flearn\u002Fexamples","2.learn\u002F4.examples\u002Findex",[138,139,143,147,151],{"title":134,"path":135,"stem":136},{"title":140,"path":141,"stem":142},"Foundation Examples","\u002Flearn\u002Fexamples\u002Ffoundations","2.learn\u002F4.examples\u002F1.foundations",{"title":144,"path":145,"stem":146},"Building Blocks","\u002Flearn\u002Fexamples\u002Fbuilding-blocks","2.learn\u002F4.examples\u002F2.building-blocks",{"title":148,"path":149,"stem":150},"Typed-Group Variants","\u002Flearn\u002Fexamples\u002Ftyped-variants","2.learn\u002F4.examples\u002F3.typed-variants",{"title":152,"path":153,"stem":154},"End-to-End Pipelines","\u002Flearn\u002Fexamples\u002Fpipelines","2.learn\u002F4.examples\u002F4.pipelines",{"title":156,"path":157,"stem":158,"children":159},"Resources","\u002Fresources","3.resources",[160,162,166,170],{"title":156,"path":157,"stem":161},"3.resources\u002Findex",{"title":163,"path":164,"stem":165},"Integrations","\u002Fresources\u002Fintegrations","3.resources\u002F1.integrations",{"title":167,"path":168,"stem":169},"Migration guide: Laco 0.x → 1.0","\u002Fresources\u002Fmigration-0.x-to-1.0","3.resources\u002F2.migration-0.x-to-1.0",{"title":171,"path":172,"stem":173},"Laco vs hydra-zen","\u002Fresources\u002Flaco-vs-hydra-zen","3.resources\u002F3.laco-vs-hydra-zen",{"title":175,"path":176,"stem":177,"children":178},"API Reference","\u002Fapi","4.api\u002Findex",[179],{"title":175,"path":176,"stem":177},{"title":181,"path":182,"stem":183},"Lazy Configuration for Python","\u002F","index",[185,188,191,194,197,200,203],{"title":186,"path":187},"cli","\u002Fapi\u002Fcli",{"title":189,"path":190},"compat","\u002Fapi\u002Fcompat",{"title":192,"path":193},"handler","\u002Fapi\u002Fhandler",{"title":195,"path":196},"keys","\u002Fapi\u002Fkeys",{"title":198,"path":199},"language","\u002Fapi\u002Flanguage",{"title":201,"path":202},"ops","\u002Fapi\u002Fops",{"title":204,"path":205},"utils","\u002Fapi\u002Futils",{"id":207,"title":55,"body":208,"description":4254,"extension":4255,"meta":4256,"navigation":4257,"path":56,"seo":4258,"stem":57,"__hash__":4259},"content\u002F2.learn\u002F1.tutorials\u002F09.tasks-and-app-loop.md",{"type":209,"value":210,"toc":4233},"minimark",[211,215,261,264,286,297,342,353,453,461,484,715,720,725,754,764,1028,1031,1038,1048,1065,1076,1126,1144,1401,1404,1511,1514,1590,1593,1597,1630,1633,2224,2227,2243,2251,2263,2266,2449,2452,2459,2471,2667,2670,2676,2743,2762,2766,2776,2856,2859,2956,2959,3041,3044,3343,3346,3353,3359,3462,3473,3479,3490,3839,3842,3847,3894,3898,3913,4086,4089,4100,4106,4110,4210,4229],[212,213,55],"h1",{"id":214},"tasks-and-the-app-loop",[216,217,218,222,223,226,229,230,234,235,238,239,242,243,242,246,249,250,252,229,255,242,258],"p",{},[219,220,221],"strong",{},"Series:"," laco tutorial notebooks",[224,225],"br",{},[219,227,228],{},"Prerequisites:"," ",[231,232,233],"code",{},"01.why-laco.ipynb"," through ",[231,236,237],{},"08.pipeline-configs.ipynb"," (especially ",[231,240,241],{},"03.lazy-call-and-partial.ipynb",", ",[231,244,245],{},"04.hyperparameters-and-interpolation.ipynb",[231,247,248],{},"07.typed-groups-and-schemas.ipynb",")",[224,251],{},[219,253,254],{},"Dependencies:",[231,256,257],{},"torch",[231,259,260],{},"torchvision",[262,263],"hr",{},[216,265,266,267,271,272,242,275,242,278,281,282,285],{},"In previous notebooks you learned how to ",[268,269,270],"em",{},"build"," configs: ",[231,273,274],{},"L.call",[231,276,277],{},"L.partial",[231,279,280],{},"@L.params",", groups, defaults. This notebook covers the other half: how to ",[268,283,284],{},"run"," them.",[216,287,288,289,292,293,296],{},"The key concept is the ",[219,290,291],{},"task function",", a callable that accepts a ",[231,294,295],{},"DictConfig"," and automatically receives its fields as fully-instantiated Python objects. Two decorators power this:",[298,299,300,313],"table",{},[301,302,303],"thead",{},[304,305,306,310],"tr",{},[307,308,309],"th",{},"Decorator",[307,311,312],{},"What it does",[314,315,316,330],"tbody",{},[304,317,318,324],{},[319,320,321],"td",{},[231,322,323],{},"@L.task",[319,325,326,327,329],{},"Unwraps a ",[231,328,295],{}," into typed kwargs for one function",[304,331,332,337],{},[319,333,334],{},[231,335,336],{},"@laco.main(config_name=...)",[319,338,339,340],{},"Hydra app entry point; composes config from file + CLI, then calls ",[231,341,323],{},[216,343,344,345,348,349,352],{},"By the end you will understand exactly what happens between ",[231,346,347],{},"laco.load(\"train.py\")"," and ",[231,350,351],{},"model.train()",".",[354,355,360],"pre",{"className":356,"code":357,"language":358,"meta":359,"style":359},"language-python shiki shiki-themes material-theme-lighter github-light github-dark","import inspect\nimport functools\n\nimport laco\nimport laco.language as L\nimport torch.nn as nn\nimport torch.optim as optim\n","python","",[231,361,362,375,383,390,398,418,436],{"__ignoreMap":359},[363,364,367,371],"span",{"class":365,"line":366},"line",1,[363,368,370],{"class":369},"sVHd0","import",[363,372,374],{"class":373},"su5hD"," inspect\n",[363,376,378,380],{"class":365,"line":377},2,[363,379,370],{"class":369},[363,381,382],{"class":373}," functools\n",[363,384,386],{"class":365,"line":385},3,[363,387,389],{"emptyLinePlaceholder":388},true,"\n",[363,391,393,395],{"class":365,"line":392},4,[363,394,370],{"class":369},[363,396,397],{"class":373}," laco\n",[363,399,401,403,406,409,412,415],{"class":365,"line":400},5,[363,402,370],{"class":369},[363,404,405],{"class":373}," laco",[363,407,352],{"class":408},"sP7_E",[363,410,198],{"class":411},"skxfh",[363,413,414],{"class":369}," as",[363,416,417],{"class":373}," L\n",[363,419,421,423,426,428,431,433],{"class":365,"line":420},6,[363,422,370],{"class":369},[363,424,425],{"class":373}," torch",[363,427,352],{"class":408},[363,429,430],{"class":411},"nn",[363,432,414],{"class":369},[363,434,435],{"class":373}," nn\n",[363,437,439,441,443,445,448,450],{"class":365,"line":438},7,[363,440,370],{"class":369},[363,442,425],{"class":373},[363,444,352],{"class":408},[363,446,447],{"class":411},"optim",[363,449,414],{"class":369},[363,451,452],{"class":373}," optim\n",[454,455,457,458,460],"h2",{"id":456},"section-1-the-problem-ltask-solves","Section 1: The problem ",[231,459,323],{}," solves",[216,462,463,464,466,467,242,470,242,473,476,477,480,481,483],{},"Suppose you have a training config loaded via ",[231,465,347],{}," that contains ",[231,468,469],{},"model",[231,471,472],{},"optimizer",[231,474,475],{},"loss",", and ",[231,478,479],{},"num_steps"," fields. Without ",[231,482,323],{},", wiring them to a function is repetitive boilerplate:",[354,485,487],{"className":356,"code":486,"language":358,"meta":359,"style":359},"# WITHOUT @L.task — verbose, error-prone, and not refactor-safe\ndef train_raw(cfg):\n    model          = laco.instantiate(cfg.model)\n    optimizer_fact = laco.instantiate(cfg.optimizer)   # functools.partial\n    optimizer      = optimizer_fact(model.parameters())\n    loss_fn        = laco.instantiate(cfg.loss)\n    num_steps      = laco.instantiate(cfg.num_steps)   # plain int — also goes through instantiate\n\n    model.train()\n    # ... training loop using model, optimizer, loss_fn, num_steps\n    print(\"train_raw: instantiation done\")\n\nprint(inspect.getsource(train_raw))\n",[231,488,489,495,515,543,569,591,614,640,645,659,665,686,691],{"__ignoreMap":359},[363,490,491],{"class":365,"line":366},[363,492,494],{"class":493},"sutJx","# WITHOUT @L.task — verbose, error-prone, and not refactor-safe\n",[363,496,497,501,505,508,512],{"class":365,"line":377},[363,498,500],{"class":499},"sbsja","def",[363,502,504],{"class":503},"sGLFI"," train_raw",[363,506,507],{"class":408},"(",[363,509,511],{"class":510},"sFwrP","cfg",[363,513,514],{"class":408},"):\n",[363,516,517,520,524,526,528,532,534,536,538,540],{"class":365,"line":385},[363,518,519],{"class":373},"    model          ",[363,521,523],{"class":522},"smGrS","=",[363,525,405],{"class":373},[363,527,352],{"class":408},[363,529,531],{"class":530},"slqww","instantiate",[363,533,507],{"class":408},[363,535,511],{"class":530},[363,537,352],{"class":408},[363,539,469],{"class":411},[363,541,542],{"class":408},")\n",[363,544,545,548,550,552,554,556,558,560,562,564,566],{"class":365,"line":392},[363,546,547],{"class":373},"    optimizer_fact ",[363,549,523],{"class":522},[363,551,405],{"class":373},[363,553,352],{"class":408},[363,555,531],{"class":530},[363,557,507],{"class":408},[363,559,511],{"class":530},[363,561,352],{"class":408},[363,563,472],{"class":411},[363,565,249],{"class":408},[363,567,568],{"class":493},"   # functools.partial\n",[363,570,571,574,576,579,581,583,585,588],{"class":365,"line":400},[363,572,573],{"class":373},"    optimizer      ",[363,575,523],{"class":522},[363,577,578],{"class":530}," optimizer_fact",[363,580,507],{"class":408},[363,582,469],{"class":530},[363,584,352],{"class":408},[363,586,587],{"class":530},"parameters",[363,589,590],{"class":408},"())\n",[363,592,593,596,598,600,602,604,606,608,610,612],{"class":365,"line":420},[363,594,595],{"class":373},"    loss_fn        ",[363,597,523],{"class":522},[363,599,405],{"class":373},[363,601,352],{"class":408},[363,603,531],{"class":530},[363,605,507],{"class":408},[363,607,511],{"class":530},[363,609,352],{"class":408},[363,611,475],{"class":411},[363,613,542],{"class":408},[363,615,616,619,621,623,625,627,629,631,633,635,637],{"class":365,"line":438},[363,617,618],{"class":373},"    num_steps      ",[363,620,523],{"class":522},[363,622,405],{"class":373},[363,624,352],{"class":408},[363,626,531],{"class":530},[363,628,507],{"class":408},[363,630,511],{"class":530},[363,632,352],{"class":408},[363,634,479],{"class":411},[363,636,249],{"class":408},[363,638,639],{"class":493},"   # plain int — also goes through instantiate\n",[363,641,643],{"class":365,"line":642},8,[363,644,389],{"emptyLinePlaceholder":388},[363,646,648,651,653,656],{"class":365,"line":647},9,[363,649,650],{"class":373},"    model",[363,652,352],{"class":408},[363,654,655],{"class":530},"train",[363,657,658],{"class":408},"()\n",[363,660,662],{"class":365,"line":661},10,[363,663,664],{"class":493},"    # ... training loop using model, optimizer, loss_fn, num_steps\n",[363,666,668,672,674,678,682,684],{"class":365,"line":667},11,[363,669,671],{"class":670},"sptTA","    print",[363,673,507],{"class":408},[363,675,677],{"class":676},"sjJ54","\"",[363,679,681],{"class":680},"s_sjI","train_raw: instantiation done",[363,683,677],{"class":676},[363,685,542],{"class":408},[363,687,689],{"class":365,"line":688},12,[363,690,389],{"emptyLinePlaceholder":388},[363,692,694,697,699,702,704,707,709,712],{"class":365,"line":693},13,[363,695,696],{"class":670},"print",[363,698,507],{"class":408},[363,700,701],{"class":530},"inspect",[363,703,352],{"class":408},[363,705,706],{"class":530},"getsource",[363,708,507],{"class":408},[363,710,711],{"class":530},"train_raw",[363,713,714],{"class":408},"))\n",[716,717],"docyard-notebook-output",{"data":718,"kind":719},"ZGVmIHRyYWluX3JhdyhjZmcpOgogICAgbW9kZWwgICAgICAgICAgPSBsYWNvLmluc3RhbnRpYXRlKGNmZy5tb2RlbCkKICAgIG9wdGltaXplcl9mYWN0ID0gbGFjby5pbnN0YW50aWF0ZShjZmcub3B0aW1pemVyKSAgICMgZnVuY3Rvb2xzLnBhcnRpYWwKICAgIG9wdGltaXplciAgICAgID0gb3B0aW1pemVyX2ZhY3QobW9kZWwucGFyYW1ldGVycygpKQogICAgbG9zc19mbiAgICAgICAgPSBsYWNvLmluc3RhbnRpYXRlKGNmZy5sb3NzKQogICAgbnVtX3N0ZXBzICAgICAgPSBsYWNvLmluc3RhbnRpYXRlKGNmZy5udW1fc3RlcHMpICAgIyBwbGFpbiBpbnQg4oCUIGFsc28gZ29lcyB0aHJvdWdoIGluc3RhbnRpYXRlCgogICAgbW9kZWwudHJhaW4oKQogICAgIyAuLi4gdHJhaW5pbmcgbG9vcCB1c2luZyBtb2RlbCwgb3B0aW1pemVyLCBsb3NzX2ZuLCBudW1fc3RlcHMKICAgIHByaW50KCJ0cmFpbl9yYXc6IGluc3RhbnRpYXRpb24gZG9uZSIpCgo=","stream",[216,721,722],{},[219,723,724],{},"Pain points:",[726,727,728,736,747],"ul",{},[729,730,731,732,735],"li",{},"Every field must be manually ",[231,733,734],{},"laco.instantiate","d.",[729,737,738,739,742,743,746],{},"If you rename a config key, you must update both the config file ",[268,740,741],{},"and"," every ",[231,744,745],{},"cfg.field_name"," access.",[729,748,749,750,753],{},"There is no static type information on ",[231,751,752],{},"cfg.model",", so the IDE can't help.",[216,755,756,757,759,760,763],{},"With ",[231,758,323],{},", laco reads your function's ",[268,761,762],{},"signature"," and does the wiring for you:",[354,765,767],{"className":356,"code":766,"language":358,"meta":359,"style":359},"# WITH @L.task — signature-driven, type-annotated, refactor-safe\n@L.task\ndef train(model: nn.Module, optimizer, loss: nn.Module, num_steps: int = 1):\n    # All fields already instantiated by @L.task!\n    # optimizer is a functools.partial — call it with model.parameters()\n    opt = optimizer(model.parameters())\n    model.train()\n    print(f\"train: model={type(model).__name__}, loss={type(loss).__name__}, steps={num_steps}\")\n\n# The decorated function now accepts a DictConfig, not positional args:\nprint(\"Signature of wrapped 'train':\", inspect.signature(train))\nprint(\"Has _laco_task marker:\", getattr(train, '_laco_task', False))\n",[231,768,769,774,788,849,854,859,878,888,950,954,959,987],{"__ignoreMap":359},[363,770,771],{"class":365,"line":366},[363,772,773],{"class":493},"# WITH @L.task — signature-driven, type-annotated, refactor-safe\n",[363,775,776,780,783,785],{"class":365,"line":377},[363,777,779],{"class":778},"stp6e","@",[363,781,782],{"class":503},"L",[363,784,352],{"class":778},[363,786,787],{"class":503},"task\n",[363,789,790,792,795,797,799,802,805,807,810,813,816,818,821,823,825,827,829,831,834,836,840,843,847],{"class":365,"line":385},[363,791,500],{"class":499},[363,793,794],{"class":503}," train",[363,796,507],{"class":408},[363,798,469],{"class":510},[363,800,801],{"class":408},":",[363,803,804],{"class":373}," nn",[363,806,352],{"class":408},[363,808,809],{"class":411},"Module",[363,811,812],{"class":408},",",[363,814,815],{"class":510}," optimizer",[363,817,812],{"class":408},[363,819,820],{"class":510}," loss",[363,822,801],{"class":408},[363,824,804],{"class":373},[363,826,352],{"class":408},[363,828,809],{"class":411},[363,830,812],{"class":408},[363,832,833],{"class":510}," num_steps",[363,835,801],{"class":408},[363,837,839],{"class":838},"sZMiF"," int",[363,841,842],{"class":522}," =",[363,844,846],{"class":845},"srdBf"," 1",[363,848,514],{"class":408},[363,850,851],{"class":365,"line":392},[363,852,853],{"class":493},"    # All fields already instantiated by @L.task!\n",[363,855,856],{"class":365,"line":400},[363,857,858],{"class":493},"    # optimizer is a functools.partial — call it with model.parameters()\n",[363,860,861,864,866,868,870,872,874,876],{"class":365,"line":420},[363,862,863],{"class":373},"    opt ",[363,865,523],{"class":522},[363,867,815],{"class":530},[363,869,507],{"class":408},[363,871,469],{"class":530},[363,873,352],{"class":408},[363,875,587],{"class":530},[363,877,590],{"class":408},[363,879,880,882,884,886],{"class":365,"line":438},[363,881,650],{"class":373},[363,883,352],{"class":408},[363,885,655],{"class":530},[363,887,658],{"class":408},[363,889,890,892,894,897,900,903,906,908,910,913,917,920,923,925,927,929,931,933,935,937,940,942,944,946,948],{"class":365,"line":642},[363,891,671],{"class":670},[363,893,507],{"class":408},[363,895,896],{"class":499},"f",[363,898,899],{"class":680},"\"train: model=",[363,901,902],{"class":845},"{",[363,904,905],{"class":838},"type",[363,907,507],{"class":408},[363,909,469],{"class":530},[363,911,912],{"class":408},").",[363,914,916],{"class":915},"s_hVV","__name__",[363,918,919],{"class":845},"}",[363,921,922],{"class":680},", loss=",[363,924,902],{"class":845},[363,926,905],{"class":838},[363,928,507],{"class":408},[363,930,475],{"class":530},[363,932,912],{"class":408},[363,934,916],{"class":915},[363,936,919],{"class":845},[363,938,939],{"class":680},", steps=",[363,941,902],{"class":845},[363,943,479],{"class":530},[363,945,919],{"class":845},[363,947,677],{"class":680},[363,949,542],{"class":408},[363,951,952],{"class":365,"line":647},[363,953,389],{"emptyLinePlaceholder":388},[363,955,956],{"class":365,"line":661},[363,957,958],{"class":493},"# The decorated function now accepts a DictConfig, not positional args:\n",[363,960,961,963,965,967,970,972,974,977,979,981,983,985],{"class":365,"line":667},[363,962,696],{"class":670},[363,964,507],{"class":408},[363,966,677],{"class":676},[363,968,969],{"class":680},"Signature of wrapped 'train':",[363,971,677],{"class":676},[363,973,812],{"class":408},[363,975,976],{"class":530}," inspect",[363,978,352],{"class":408},[363,980,762],{"class":530},[363,982,507],{"class":408},[363,984,655],{"class":530},[363,986,714],{"class":408},[363,988,989,991,993,995,998,1000,1002,1005,1007,1009,1011,1014,1017,1020,1022,1026],{"class":365,"line":688},[363,990,696],{"class":670},[363,992,507],{"class":408},[363,994,677],{"class":676},[363,996,997],{"class":680},"Has _laco_task marker:",[363,999,677],{"class":676},[363,1001,812],{"class":408},[363,1003,1004],{"class":670}," getattr",[363,1006,507],{"class":408},[363,1008,655],{"class":530},[363,1010,812],{"class":408},[363,1012,1013],{"class":676}," '",[363,1015,1016],{"class":680},"_laco_task",[363,1018,1019],{"class":676},"'",[363,1021,812],{"class":408},[363,1023,1025],{"class":1024},"s39Yj"," False",[363,1027,714],{"class":408},[716,1029],{"data":1030,"kind":719},"U2lnbmF0dXJlIG9mIHdyYXBwZWQgJ3RyYWluJzogKG1vZGVsOiB0b3JjaC5ubi5tb2R1bGVzLm1vZHVsZS5Nb2R1bGUsIG9wdGltaXplciwgbG9zczogdG9yY2gubm4ubW9kdWxlcy5tb2R1bGUuTW9kdWxlLCBudW1fc3RlcHM6IGludCA9IDEpCkhhcyBfbGFjb190YXNrIG1hcmtlcjogVHJ1ZQo=",[454,1032,1034,1035,1037],{"id":1033},"section-2-ltask-internals-step-by-step","Section 2: ",[231,1036,323],{}," internals, step by step",[216,1039,1040,1041,1043,1044,1047],{},"When you write ",[231,1042,323],{}," on a function, laco does the following ",[219,1045,1046],{},"at decoration time"," (once, not on every call):",[1049,1050,1051],"ol",{},[729,1052,1053,1056,1057,242,1059,242,1061,242,1063],{},[231,1054,1055],{},"inspect.signature(train)"," → discovers parameter names: ",[231,1058,469],{},[231,1060,472],{},[231,1062,475],{},[231,1064,479],{},[216,1066,1067,1068,1071,1072,1075],{},"Then ",[219,1069,1070],{},"at call time"," (each time you call ",[231,1073,1074],{},"train(cfg)","):",[1049,1077,1078,1110,1120],{"start":377},[729,1079,1080,1081,1083,1084],{},"For each parameter name ",[231,1082,216],{},":\n",[726,1085,1086,1096],{},[729,1087,1088,1091,1092,1095],{},[231,1089,1090],{},"OmegaConf.select(cfg, p)"," → retrieves the sub-tree (or ",[231,1093,1094],{},"SENTINEL"," if absent)",[729,1097,1098,1101,1102,1105,1106,1109],{},[231,1099,1100],{},"laco.instantiate(sub_tree)"," → materializes it: ",[231,1103,1104],{},"DictConfig{_target_: nn.Linear ...}"," → ",[231,1107,1108],{},"nn.Linear"," object",[729,1111,1112,1113,1115,1116,1119],{},"If a required parameter is missing from the config ",[268,1114,741],{}," has no default: ",[231,1117,1118],{},"TypeError"," with clear message",[729,1121,1122,1125],{},[231,1123,1124],{},"train(model=model_obj, optimizer=partial_obj, loss=loss_obj, num_steps=1)",": the original body runs",[216,1127,1128,1129,1132,1133,1136,1137,1140,1141,1143],{},"VAR_POSITIONAL (",[231,1130,1131],{},"*args",") and VAR_KEYWORD (",[231,1134,1135],{},"**kwargs",") parameters are ",[219,1138,1139],{},"skipped",": ",[231,1142,323],{}," only maps named parameters.",[354,1145,1147],{"className":356,"code":1146,"language":358,"meta":359,"style":359},"# Manually reproduce what @L.task does, for pedagogical clarity:\nfrom omegaconf import OmegaConf\n\n# Build a toy config manually (no file needed)\ncfg_manual = OmegaConf.create({\n    \"value\": 42,\n    \"scale\": 2.5,\n})\n\n@L.task\ndef process(value: int, scale: float = 1.0) -> float:\n    result = value * scale\n    print(f\"process(value={value}, scale={scale}) = {result}\")\n    return result\n\n# The task reads 'value' and 'scale' from the DictConfig:\nresult = process(cfg_manual)\nprint(f\"Result: {result}\")\n",[231,1148,1149,1154,1167,1171,1176,1194,1212,1228,1233,1237,1247,1286,1302,1342,1351,1356,1362,1379],{"__ignoreMap":359},[363,1150,1151],{"class":365,"line":366},[363,1152,1153],{"class":493},"# Manually reproduce what @L.task does, for pedagogical clarity:\n",[363,1155,1156,1159,1162,1164],{"class":365,"line":377},[363,1157,1158],{"class":369},"from",[363,1160,1161],{"class":373}," omegaconf ",[363,1163,370],{"class":369},[363,1165,1166],{"class":373}," OmegaConf\n",[363,1168,1169],{"class":365,"line":385},[363,1170,389],{"emptyLinePlaceholder":388},[363,1172,1173],{"class":365,"line":392},[363,1174,1175],{"class":493},"# Build a toy config manually (no file needed)\n",[363,1177,1178,1181,1183,1186,1188,1191],{"class":365,"line":400},[363,1179,1180],{"class":373},"cfg_manual ",[363,1182,523],{"class":522},[363,1184,1185],{"class":373}," OmegaConf",[363,1187,352],{"class":408},[363,1189,1190],{"class":530},"create",[363,1192,1193],{"class":408},"({\n",[363,1195,1196,1199,1202,1204,1206,1209],{"class":365,"line":420},[363,1197,1198],{"class":676},"    \"",[363,1200,1201],{"class":680},"value",[363,1203,677],{"class":676},[363,1205,801],{"class":408},[363,1207,1208],{"class":845}," 42",[363,1210,1211],{"class":408},",\n",[363,1213,1214,1216,1219,1221,1223,1226],{"class":365,"line":438},[363,1215,1198],{"class":676},[363,1217,1218],{"class":680},"scale",[363,1220,677],{"class":676},[363,1222,801],{"class":408},[363,1224,1225],{"class":845}," 2.5",[363,1227,1211],{"class":408},[363,1229,1230],{"class":365,"line":642},[363,1231,1232],{"class":408},"})\n",[363,1234,1235],{"class":365,"line":647},[363,1236,389],{"emptyLinePlaceholder":388},[363,1238,1239,1241,1243,1245],{"class":365,"line":661},[363,1240,779],{"class":778},[363,1242,782],{"class":503},[363,1244,352],{"class":778},[363,1246,787],{"class":503},[363,1248,1249,1251,1254,1256,1258,1260,1262,1264,1267,1269,1272,1274,1277,1279,1282,1284],{"class":365,"line":667},[363,1250,500],{"class":499},[363,1252,1253],{"class":503}," process",[363,1255,507],{"class":408},[363,1257,1201],{"class":510},[363,1259,801],{"class":408},[363,1261,839],{"class":838},[363,1263,812],{"class":408},[363,1265,1266],{"class":510}," scale",[363,1268,801],{"class":408},[363,1270,1271],{"class":838}," float",[363,1273,842],{"class":522},[363,1275,1276],{"class":845}," 1.0",[363,1278,249],{"class":408},[363,1280,1281],{"class":408}," ->",[363,1283,1271],{"class":838},[363,1285,1083],{"class":408},[363,1287,1288,1291,1293,1296,1299],{"class":365,"line":688},[363,1289,1290],{"class":373},"    result ",[363,1292,523],{"class":522},[363,1294,1295],{"class":373}," value ",[363,1297,1298],{"class":522},"*",[363,1300,1301],{"class":373}," scale\n",[363,1303,1304,1306,1308,1310,1313,1315,1317,1319,1322,1324,1326,1328,1331,1333,1336,1338,1340],{"class":365,"line":693},[363,1305,671],{"class":670},[363,1307,507],{"class":408},[363,1309,896],{"class":499},[363,1311,1312],{"class":680},"\"process(value=",[363,1314,902],{"class":845},[363,1316,1201],{"class":530},[363,1318,919],{"class":845},[363,1320,1321],{"class":680},", scale=",[363,1323,902],{"class":845},[363,1325,1218],{"class":530},[363,1327,919],{"class":845},[363,1329,1330],{"class":680},") = ",[363,1332,902],{"class":845},[363,1334,1335],{"class":530},"result",[363,1337,919],{"class":845},[363,1339,677],{"class":680},[363,1341,542],{"class":408},[363,1343,1345,1348],{"class":365,"line":1344},14,[363,1346,1347],{"class":369},"    return",[363,1349,1350],{"class":373}," result\n",[363,1352,1354],{"class":365,"line":1353},15,[363,1355,389],{"emptyLinePlaceholder":388},[363,1357,1359],{"class":365,"line":1358},16,[363,1360,1361],{"class":493},"# The task reads 'value' and 'scale' from the DictConfig:\n",[363,1363,1365,1368,1370,1372,1374,1377],{"class":365,"line":1364},17,[363,1366,1367],{"class":373},"result ",[363,1369,523],{"class":522},[363,1371,1253],{"class":530},[363,1373,507],{"class":408},[363,1375,1376],{"class":530},"cfg_manual",[363,1378,542],{"class":408},[363,1380,1382,1384,1386,1388,1391,1393,1395,1397,1399],{"class":365,"line":1381},18,[363,1383,696],{"class":670},[363,1385,507],{"class":408},[363,1387,896],{"class":499},[363,1389,1390],{"class":680},"\"Result: ",[363,1392,902],{"class":845},[363,1394,1335],{"class":530},[363,1396,919],{"class":845},[363,1398,677],{"class":680},[363,1400,542],{"class":408},[716,1402],{"data":1403,"kind":719},"cHJvY2Vzcyh2YWx1ZT00Miwgc2NhbGU9Mi41KSA9IDEwNS4wClJlc3VsdDogMTA1LjAK",[354,1405,1407],{"className":356,"code":1406,"language":358,"meta":359,"style":359},"# What happens when a required parameter is missing?\ncfg_incomplete = OmegaConf.create({\"scale\": 3.0})  # 'value' is absent and has no default\n\ntry:\n    process(cfg_incomplete)\nexcept TypeError as e:\n    print(\"TypeError caught (required param missing):\")\n    print(e)\n",[231,1408,1409,1414,1447,1451,1458,1470,1485,1500],{"__ignoreMap":359},[363,1410,1411],{"class":365,"line":366},[363,1412,1413],{"class":493},"# What happens when a required parameter is missing?\n",[363,1415,1416,1419,1421,1423,1425,1427,1430,1432,1434,1436,1438,1441,1444],{"class":365,"line":377},[363,1417,1418],{"class":373},"cfg_incomplete ",[363,1420,523],{"class":522},[363,1422,1185],{"class":373},[363,1424,352],{"class":408},[363,1426,1190],{"class":530},[363,1428,1429],{"class":408},"({",[363,1431,677],{"class":676},[363,1433,1218],{"class":680},[363,1435,677],{"class":676},[363,1437,801],{"class":408},[363,1439,1440],{"class":845}," 3.0",[363,1442,1443],{"class":408},"})",[363,1445,1446],{"class":493},"  # 'value' is absent and has no default\n",[363,1448,1449],{"class":365,"line":385},[363,1450,389],{"emptyLinePlaceholder":388},[363,1452,1453,1456],{"class":365,"line":392},[363,1454,1455],{"class":369},"try",[363,1457,1083],{"class":408},[363,1459,1460,1463,1465,1468],{"class":365,"line":400},[363,1461,1462],{"class":530},"    process",[363,1464,507],{"class":408},[363,1466,1467],{"class":530},"cfg_incomplete",[363,1469,542],{"class":408},[363,1471,1472,1475,1478,1480,1483],{"class":365,"line":420},[363,1473,1474],{"class":369},"except",[363,1476,1477],{"class":838}," TypeError",[363,1479,414],{"class":369},[363,1481,1482],{"class":373}," e",[363,1484,1083],{"class":408},[363,1486,1487,1489,1491,1493,1496,1498],{"class":365,"line":438},[363,1488,671],{"class":670},[363,1490,507],{"class":408},[363,1492,677],{"class":676},[363,1494,1495],{"class":680},"TypeError caught (required param missing):",[363,1497,677],{"class":676},[363,1499,542],{"class":408},[363,1501,1502,1504,1506,1509],{"class":365,"line":642},[363,1503,671],{"class":670},[363,1505,507],{"class":408},[363,1507,1508],{"class":530},"e",[363,1510,542],{"class":408},[716,1512],{"data":1513,"kind":719},"VHlwZUVycm9yIGNhdWdodCAocmVxdWlyZWQgcGFyYW0gbWlzc2luZyk6CkBMLnRhc2socHJvY2Vzcyk6IHJlcXVpcmVkIHBhcmFtZXRlciAndmFsdWUnIG5vdCBmb3VuZCBpbiBjb25maWcuIEF2YWlsYWJsZSBrZXlzOiBbJ3NjYWxlJ10K",[354,1515,1517],{"className":356,"code":1516,"language":358,"meta":359,"style":359},"# Parameters with defaults: omitting 'scale' is fine — the function default applies.\ncfg_no_scale = OmegaConf.create({\"value\": 10})\nresult_default = process(cfg_no_scale)\nprint(f\"Result with default scale: {result_default}\")\n",[231,1518,1519,1524,1552,1568],{"__ignoreMap":359},[363,1520,1521],{"class":365,"line":366},[363,1522,1523],{"class":493},"# Parameters with defaults: omitting 'scale' is fine — the function default applies.\n",[363,1525,1526,1529,1531,1533,1535,1537,1539,1541,1543,1545,1547,1550],{"class":365,"line":377},[363,1527,1528],{"class":373},"cfg_no_scale ",[363,1530,523],{"class":522},[363,1532,1185],{"class":373},[363,1534,352],{"class":408},[363,1536,1190],{"class":530},[363,1538,1429],{"class":408},[363,1540,677],{"class":676},[363,1542,1201],{"class":680},[363,1544,677],{"class":676},[363,1546,801],{"class":408},[363,1548,1549],{"class":845}," 10",[363,1551,1232],{"class":408},[363,1553,1554,1557,1559,1561,1563,1566],{"class":365,"line":385},[363,1555,1556],{"class":373},"result_default ",[363,1558,523],{"class":522},[363,1560,1253],{"class":530},[363,1562,507],{"class":408},[363,1564,1565],{"class":530},"cfg_no_scale",[363,1567,542],{"class":408},[363,1569,1570,1572,1574,1576,1579,1581,1584,1586,1588],{"class":365,"line":392},[363,1571,696],{"class":670},[363,1573,507],{"class":408},[363,1575,896],{"class":499},[363,1577,1578],{"class":680},"\"Result with default scale: ",[363,1580,902],{"class":845},[363,1582,1583],{"class":530},"result_default",[363,1585,919],{"class":845},[363,1587,677],{"class":680},[363,1589,542],{"class":408},[716,1591],{"data":1592,"kind":719},"cHJvY2Vzcyh2YWx1ZT0xMCwgc2NhbGU9MS4wKSA9IDEwLjAKUmVzdWx0IHdpdGggZGVmYXVsdCBzY2FsZTogMTAuMAo=",[454,1594,1596],{"id":1595},"section-3-the-optimizer-partial-pattern","Section 3: The optimizer partial pattern",[216,1598,1599,1600,1602,1603,1606,1607,1610,1611,1614,1615,1617,1618,242,1621,1623,1624,1627,1628,352],{},"The most important ",[231,1601,323],{}," use case is the ",[219,1604,1605],{},"optimizer partial pattern",". Optimizers like ",[231,1608,1609],{},"Adam"," need ",[231,1612,1613],{},"model.parameters()",", which only exists after the model is built. laco solves this with ",[231,1616,277],{},": the config stores ",[231,1619,1620],{},"_partial_: true",[231,1622,734],{}," returns a ",[231,1625,1626],{},"functools.partial",", and the task body calls it with ",[231,1629,1613],{},[216,1631,1632],{},"This is exactly how the MNIST pipeline works:",[354,1634,1636],{"className":356,"code":1635,"language":358,"meta":359,"style":359},"# Build a small config that mimics the MNIST pipeline structure:\nmodel_cfg     = L.call(nn.Linear)(in_features=4, out_features=2)\noptimizer_cfg = L.partial(optim.SGD)(lr=1e-2, momentum=0.9)\nloss_cfg      = L.call(nn.CrossEntropyLoss)()\n\ncombined_cfg = OmegaConf.create({\n    \"model\":     OmegaConf.to_container(model_cfg,     resolve=False),\n    \"optimizer\": OmegaConf.to_container(optimizer_cfg, resolve=False),\n    \"loss\":      OmegaConf.to_container(loss_cfg,      resolve=False),\n    \"num_steps\": 2,\n})\n\n@L.task\ndef mini_train(model: nn.Module, optimizer, loss: nn.Module, num_steps: int = 1):\n    # At this point:\n    #   model     — a real nn.Linear\n    #   optimizer — a functools.partial(SGD, lr=0.01, momentum=0.9)\n    #   loss      — a real nn.CrossEntropyLoss\n    print(f\"model type     : {type(model).__name__}\")\n    print(f\"optimizer type : {type(optimizer).__name__}\")\n    print(f\"loss type      : {type(loss).__name__}\")\n    print(f\"num_steps      : {num_steps}\")\n\n    # Now create the full optimizer using model.parameters():\n    opt = optimizer(model.parameters())  # functools.partial called here\n    print(f\"opt type       : {type(opt).__name__}\")\n    print(f\"opt lr         : {opt.param_groups[0]['lr']}\")\n\nmini_train(combined_cfg)\n",[231,1637,1638,1643,1691,1737,1762,1766,1781,1817,1849,1882,1897,1901,1905,1915,1964,1969,1974,1979,1984,2014,2044,2074,2096,2101,2107,2130,2161,2206,2211],{"__ignoreMap":359},[363,1639,1640],{"class":365,"line":366},[363,1641,1642],{"class":493},"# Build a small config that mimics the MNIST pipeline structure:\n",[363,1644,1645,1648,1650,1653,1655,1658,1660,1662,1664,1667,1670,1674,1676,1679,1681,1684,1686,1689],{"class":365,"line":377},[363,1646,1647],{"class":373},"model_cfg     ",[363,1649,523],{"class":522},[363,1651,1652],{"class":373}," L",[363,1654,352],{"class":408},[363,1656,1657],{"class":530},"call",[363,1659,507],{"class":408},[363,1661,430],{"class":530},[363,1663,352],{"class":408},[363,1665,1666],{"class":411},"Linear",[363,1668,1669],{"class":408},")(",[363,1671,1673],{"class":1672},"s99_P","in_features",[363,1675,523],{"class":522},[363,1677,1678],{"class":845},"4",[363,1680,812],{"class":408},[363,1682,1683],{"class":1672}," out_features",[363,1685,523],{"class":522},[363,1687,1688],{"class":845},"2",[363,1690,542],{"class":408},[363,1692,1693,1696,1698,1700,1702,1705,1707,1709,1711,1715,1717,1720,1722,1725,1727,1730,1732,1735],{"class":365,"line":385},[363,1694,1695],{"class":373},"optimizer_cfg ",[363,1697,523],{"class":522},[363,1699,1652],{"class":373},[363,1701,352],{"class":408},[363,1703,1704],{"class":530},"partial",[363,1706,507],{"class":408},[363,1708,447],{"class":530},[363,1710,352],{"class":408},[363,1712,1714],{"class":1713},"swQdS","SGD",[363,1716,1669],{"class":408},[363,1718,1719],{"class":1672},"lr",[363,1721,523],{"class":522},[363,1723,1724],{"class":845},"1e-2",[363,1726,812],{"class":408},[363,1728,1729],{"class":1672}," momentum",[363,1731,523],{"class":522},[363,1733,1734],{"class":845},"0.9",[363,1736,542],{"class":408},[363,1738,1739,1742,1744,1746,1748,1750,1752,1754,1756,1759],{"class":365,"line":392},[363,1740,1741],{"class":373},"loss_cfg      ",[363,1743,523],{"class":522},[363,1745,1652],{"class":373},[363,1747,352],{"class":408},[363,1749,1657],{"class":530},[363,1751,507],{"class":408},[363,1753,430],{"class":530},[363,1755,352],{"class":408},[363,1757,1758],{"class":411},"CrossEntropyLoss",[363,1760,1761],{"class":408},")()\n",[363,1763,1764],{"class":365,"line":400},[363,1765,389],{"emptyLinePlaceholder":388},[363,1767,1768,1771,1773,1775,1777,1779],{"class":365,"line":420},[363,1769,1770],{"class":373},"combined_cfg ",[363,1772,523],{"class":522},[363,1774,1185],{"class":373},[363,1776,352],{"class":408},[363,1778,1190],{"class":530},[363,1780,1193],{"class":408},[363,1782,1783,1785,1787,1789,1791,1794,1796,1799,1801,1804,1806,1809,1811,1814],{"class":365,"line":438},[363,1784,1198],{"class":676},[363,1786,469],{"class":680},[363,1788,677],{"class":676},[363,1790,801],{"class":408},[363,1792,1793],{"class":530},"     OmegaConf",[363,1795,352],{"class":408},[363,1797,1798],{"class":530},"to_container",[363,1800,507],{"class":408},[363,1802,1803],{"class":530},"model_cfg",[363,1805,812],{"class":408},[363,1807,1808],{"class":1672},"     resolve",[363,1810,523],{"class":522},[363,1812,1813],{"class":1024},"False",[363,1815,1816],{"class":408},"),\n",[363,1818,1819,1821,1823,1825,1827,1829,1831,1833,1835,1838,1840,1843,1845,1847],{"class":365,"line":642},[363,1820,1198],{"class":676},[363,1822,472],{"class":680},[363,1824,677],{"class":676},[363,1826,801],{"class":408},[363,1828,1185],{"class":530},[363,1830,352],{"class":408},[363,1832,1798],{"class":530},[363,1834,507],{"class":408},[363,1836,1837],{"class":530},"optimizer_cfg",[363,1839,812],{"class":408},[363,1841,1842],{"class":1672}," resolve",[363,1844,523],{"class":522},[363,1846,1813],{"class":1024},[363,1848,1816],{"class":408},[363,1850,1851,1853,1855,1857,1859,1862,1864,1866,1868,1871,1873,1876,1878,1880],{"class":365,"line":647},[363,1852,1198],{"class":676},[363,1854,475],{"class":680},[363,1856,677],{"class":676},[363,1858,801],{"class":408},[363,1860,1861],{"class":530},"      OmegaConf",[363,1863,352],{"class":408},[363,1865,1798],{"class":530},[363,1867,507],{"class":408},[363,1869,1870],{"class":530},"loss_cfg",[363,1872,812],{"class":408},[363,1874,1875],{"class":1672},"      resolve",[363,1877,523],{"class":522},[363,1879,1813],{"class":1024},[363,1881,1816],{"class":408},[363,1883,1884,1886,1888,1890,1892,1895],{"class":365,"line":661},[363,1885,1198],{"class":676},[363,1887,479],{"class":680},[363,1889,677],{"class":676},[363,1891,801],{"class":408},[363,1893,1894],{"class":845}," 2",[363,1896,1211],{"class":408},[363,1898,1899],{"class":365,"line":667},[363,1900,1232],{"class":408},[363,1902,1903],{"class":365,"line":688},[363,1904,389],{"emptyLinePlaceholder":388},[363,1906,1907,1909,1911,1913],{"class":365,"line":693},[363,1908,779],{"class":778},[363,1910,782],{"class":503},[363,1912,352],{"class":778},[363,1914,787],{"class":503},[363,1916,1917,1919,1922,1924,1926,1928,1930,1932,1934,1936,1938,1940,1942,1944,1946,1948,1950,1952,1954,1956,1958,1960,1962],{"class":365,"line":1344},[363,1918,500],{"class":499},[363,1920,1921],{"class":503}," mini_train",[363,1923,507],{"class":408},[363,1925,469],{"class":510},[363,1927,801],{"class":408},[363,1929,804],{"class":373},[363,1931,352],{"class":408},[363,1933,809],{"class":411},[363,1935,812],{"class":408},[363,1937,815],{"class":510},[363,1939,812],{"class":408},[363,1941,820],{"class":510},[363,1943,801],{"class":408},[363,1945,804],{"class":373},[363,1947,352],{"class":408},[363,1949,809],{"class":411},[363,1951,812],{"class":408},[363,1953,833],{"class":510},[363,1955,801],{"class":408},[363,1957,839],{"class":838},[363,1959,842],{"class":522},[363,1961,846],{"class":845},[363,1963,514],{"class":408},[363,1965,1966],{"class":365,"line":1353},[363,1967,1968],{"class":493},"    # At this point:\n",[363,1970,1971],{"class":365,"line":1358},[363,1972,1973],{"class":493},"    #   model     — a real nn.Linear\n",[363,1975,1976],{"class":365,"line":1364},[363,1977,1978],{"class":493},"    #   optimizer — a functools.partial(SGD, lr=0.01, momentum=0.9)\n",[363,1980,1981],{"class":365,"line":1381},[363,1982,1983],{"class":493},"    #   loss      — a real nn.CrossEntropyLoss\n",[363,1985,1987,1989,1991,1993,1996,1998,2000,2002,2004,2006,2008,2010,2012],{"class":365,"line":1986},19,[363,1988,671],{"class":670},[363,1990,507],{"class":408},[363,1992,896],{"class":499},[363,1994,1995],{"class":680},"\"model type     : ",[363,1997,902],{"class":845},[363,1999,905],{"class":838},[363,2001,507],{"class":408},[363,2003,469],{"class":530},[363,2005,912],{"class":408},[363,2007,916],{"class":915},[363,2009,919],{"class":845},[363,2011,677],{"class":680},[363,2013,542],{"class":408},[363,2015,2017,2019,2021,2023,2026,2028,2030,2032,2034,2036,2038,2040,2042],{"class":365,"line":2016},20,[363,2018,671],{"class":670},[363,2020,507],{"class":408},[363,2022,896],{"class":499},[363,2024,2025],{"class":680},"\"optimizer type : ",[363,2027,902],{"class":845},[363,2029,905],{"class":838},[363,2031,507],{"class":408},[363,2033,472],{"class":530},[363,2035,912],{"class":408},[363,2037,916],{"class":915},[363,2039,919],{"class":845},[363,2041,677],{"class":680},[363,2043,542],{"class":408},[363,2045,2047,2049,2051,2053,2056,2058,2060,2062,2064,2066,2068,2070,2072],{"class":365,"line":2046},21,[363,2048,671],{"class":670},[363,2050,507],{"class":408},[363,2052,896],{"class":499},[363,2054,2055],{"class":680},"\"loss type      : ",[363,2057,902],{"class":845},[363,2059,905],{"class":838},[363,2061,507],{"class":408},[363,2063,475],{"class":530},[363,2065,912],{"class":408},[363,2067,916],{"class":915},[363,2069,919],{"class":845},[363,2071,677],{"class":680},[363,2073,542],{"class":408},[363,2075,2077,2079,2081,2083,2086,2088,2090,2092,2094],{"class":365,"line":2076},22,[363,2078,671],{"class":670},[363,2080,507],{"class":408},[363,2082,896],{"class":499},[363,2084,2085],{"class":680},"\"num_steps      : ",[363,2087,902],{"class":845},[363,2089,479],{"class":530},[363,2091,919],{"class":845},[363,2093,677],{"class":680},[363,2095,542],{"class":408},[363,2097,2099],{"class":365,"line":2098},23,[363,2100,389],{"emptyLinePlaceholder":388},[363,2102,2104],{"class":365,"line":2103},24,[363,2105,2106],{"class":493},"    # Now create the full optimizer using model.parameters():\n",[363,2108,2110,2112,2114,2116,2118,2120,2122,2124,2127],{"class":365,"line":2109},25,[363,2111,863],{"class":373},[363,2113,523],{"class":522},[363,2115,815],{"class":530},[363,2117,507],{"class":408},[363,2119,469],{"class":530},[363,2121,352],{"class":408},[363,2123,587],{"class":530},[363,2125,2126],{"class":408},"())",[363,2128,2129],{"class":493},"  # functools.partial called here\n",[363,2131,2133,2135,2137,2139,2142,2144,2146,2148,2151,2153,2155,2157,2159],{"class":365,"line":2132},26,[363,2134,671],{"class":670},[363,2136,507],{"class":408},[363,2138,896],{"class":499},[363,2140,2141],{"class":680},"\"opt type       : ",[363,2143,902],{"class":845},[363,2145,905],{"class":838},[363,2147,507],{"class":408},[363,2149,2150],{"class":530},"opt",[363,2152,912],{"class":408},[363,2154,916],{"class":915},[363,2156,919],{"class":845},[363,2158,677],{"class":680},[363,2160,542],{"class":408},[363,2162,2164,2166,2168,2170,2173,2175,2177,2179,2182,2185,2188,2191,2193,2195,2197,2200,2202,2204],{"class":365,"line":2163},27,[363,2165,671],{"class":670},[363,2167,507],{"class":408},[363,2169,896],{"class":499},[363,2171,2172],{"class":680},"\"opt lr         : ",[363,2174,902],{"class":845},[363,2176,2150],{"class":530},[363,2178,352],{"class":408},[363,2180,2181],{"class":411},"param_groups",[363,2183,2184],{"class":408},"[",[363,2186,2187],{"class":845},"0",[363,2189,2190],{"class":408},"][",[363,2192,1019],{"class":676},[363,2194,1719],{"class":680},[363,2196,1019],{"class":676},[363,2198,2199],{"class":408},"]",[363,2201,919],{"class":845},[363,2203,677],{"class":680},[363,2205,542],{"class":408},[363,2207,2209],{"class":365,"line":2208},28,[363,2210,389],{"emptyLinePlaceholder":388},[363,2212,2214,2217,2219,2222],{"class":365,"line":2213},29,[363,2215,2216],{"class":530},"mini_train",[363,2218,507],{"class":408},[363,2220,2221],{"class":530},"combined_cfg",[363,2223,542],{"class":408},[716,2225],{"data":2226,"kind":719},"bW9kZWwgdHlwZSAgICAgOiBMaW5lYXIKb3B0aW1pemVyIHR5cGUgOiBwYXJ0aWFsCmxvc3MgdHlwZSAgICAgIDogQ3Jvc3NFbnRyb3B5TG9zcwpudW1fc3RlcHMgICAgICA6IDIKb3B0IHR5cGUgICAgICAgOiBTR0QKb3B0IGxyICAgICAgICAgOiAwLjAxCg==",[216,2228,2229,2232,2233,2235,2236,2238,2239,2242],{},[219,2230,2231],{},"Key insight:"," The ",[231,2234,472],{}," parameter in the function body is a ",[231,2237,1626],{},", not yet a full optimizer. The task body must call ",[231,2240,2241],{},"optimizer(model.parameters())"," to create the optimizer. This two-step pattern is intentional: it keeps the config pure (no live objects) while still allowing the optimizer to capture the model's parameters at the right time.",[454,2244,2246,2247,2250],{"id":2245},"section-4-lacomain-the-full-hydra-app","Section 4: ",[231,2248,2249],{},"@laco.main",", the full Hydra app",[216,2252,2253,2255,2256,2259,2260,2262],{},[231,2254,2249],{}," is the entry point for scripts you run from the command line. It wraps ",[231,2257,2258],{},"@hydra.main"," and automatically applies ",[231,2261,323],{}," semantics. The result: Hydra handles config composition and CLI overrides; laco handles instantiation and kwarg mapping.",[216,2264,2265],{},"Typical usage in a training script:",[354,2267,2269],{"className":356,"code":2268,"language":358,"meta":359,"style":359},"# Illustrative — the pattern used in mnist_train.py and clm_finetune.py:\n\n# import laco\n# import laco.language as L\n# from torch import nn, optim\n#\n# @laco.main(config_name=\"train\", config_path=\"configs\")\n# @L.task\n# def run(model: nn.Module, optimizer, loss: nn.Module, num_steps: int = 10):\n#     opt = optimizer(model.parameters())\n#     model.train()\n#     for step in range(num_steps):\n#         ...  # training step\n#\n# if __name__ == \"__main__\":\n#     run()  # Hydra takes over; parses argv; composes config; calls @L.task wrapper\n\nprint(\"Pattern shown above (not executed in notebook — requires __main__ guard)\")\nprint()\nprint(\"Execution flow:\")\nprint(\"  1. run()             → Hydra parses sys.argv\")\nprint(\"  2. Hydra composes    → builds DictConfig from config_name + overrides\")\nprint(\"  3. @L.task unwraps   → instantiates each field matching a parameter\")\nprint(\"  4. run body executes → receives typed, instantiated objects\")\n",[231,2270,2271,2276,2280,2285,2290,2295,2300,2305,2310,2315,2320,2325,2330,2335,2339,2344,2349,2353,2368,2374,2389,2404,2419,2434],{"__ignoreMap":359},[363,2272,2273],{"class":365,"line":366},[363,2274,2275],{"class":493},"# Illustrative — the pattern used in mnist_train.py and clm_finetune.py:\n",[363,2277,2278],{"class":365,"line":377},[363,2279,389],{"emptyLinePlaceholder":388},[363,2281,2282],{"class":365,"line":385},[363,2283,2284],{"class":493},"# import laco\n",[363,2286,2287],{"class":365,"line":392},[363,2288,2289],{"class":493},"# import laco.language as L\n",[363,2291,2292],{"class":365,"line":400},[363,2293,2294],{"class":493},"# from torch import nn, optim\n",[363,2296,2297],{"class":365,"line":420},[363,2298,2299],{"class":493},"#\n",[363,2301,2302],{"class":365,"line":438},[363,2303,2304],{"class":493},"# @laco.main(config_name=\"train\", config_path=\"configs\")\n",[363,2306,2307],{"class":365,"line":642},[363,2308,2309],{"class":493},"# @L.task\n",[363,2311,2312],{"class":365,"line":647},[363,2313,2314],{"class":493},"# def run(model: nn.Module, optimizer, loss: nn.Module, num_steps: int = 10):\n",[363,2316,2317],{"class":365,"line":661},[363,2318,2319],{"class":493},"#     opt = optimizer(model.parameters())\n",[363,2321,2322],{"class":365,"line":667},[363,2323,2324],{"class":493},"#     model.train()\n",[363,2326,2327],{"class":365,"line":688},[363,2328,2329],{"class":493},"#     for step in range(num_steps):\n",[363,2331,2332],{"class":365,"line":693},[363,2333,2334],{"class":493},"#         ...  # training step\n",[363,2336,2337],{"class":365,"line":1344},[363,2338,2299],{"class":493},[363,2340,2341],{"class":365,"line":1353},[363,2342,2343],{"class":493},"# if __name__ == \"__main__\":\n",[363,2345,2346],{"class":365,"line":1358},[363,2347,2348],{"class":493},"#     run()  # Hydra takes over; parses argv; composes config; calls @L.task wrapper\n",[363,2350,2351],{"class":365,"line":1364},[363,2352,389],{"emptyLinePlaceholder":388},[363,2354,2355,2357,2359,2361,2364,2366],{"class":365,"line":1381},[363,2356,696],{"class":670},[363,2358,507],{"class":408},[363,2360,677],{"class":676},[363,2362,2363],{"class":680},"Pattern shown above (not executed in notebook — requires __main__ guard)",[363,2365,677],{"class":676},[363,2367,542],{"class":408},[363,2369,2370,2372],{"class":365,"line":1986},[363,2371,696],{"class":670},[363,2373,658],{"class":408},[363,2375,2376,2378,2380,2382,2385,2387],{"class":365,"line":2016},[363,2377,696],{"class":670},[363,2379,507],{"class":408},[363,2381,677],{"class":676},[363,2383,2384],{"class":680},"Execution flow:",[363,2386,677],{"class":676},[363,2388,542],{"class":408},[363,2390,2391,2393,2395,2397,2400,2402],{"class":365,"line":2046},[363,2392,696],{"class":670},[363,2394,507],{"class":408},[363,2396,677],{"class":676},[363,2398,2399],{"class":680},"  1. run()             → Hydra parses sys.argv",[363,2401,677],{"class":676},[363,2403,542],{"class":408},[363,2405,2406,2408,2410,2412,2415,2417],{"class":365,"line":2076},[363,2407,696],{"class":670},[363,2409,507],{"class":408},[363,2411,677],{"class":676},[363,2413,2414],{"class":680},"  2. Hydra composes    → builds DictConfig from config_name + overrides",[363,2416,677],{"class":676},[363,2418,542],{"class":408},[363,2420,2421,2423,2425,2427,2430,2432],{"class":365,"line":2098},[363,2422,696],{"class":670},[363,2424,507],{"class":408},[363,2426,677],{"class":676},[363,2428,2429],{"class":680},"  3. @L.task unwraps   → instantiates each field matching a parameter",[363,2431,677],{"class":676},[363,2433,542],{"class":408},[363,2435,2436,2438,2440,2442,2445,2447],{"class":365,"line":2103},[363,2437,696],{"class":670},[363,2439,507],{"class":408},[363,2441,677],{"class":676},[363,2443,2444],{"class":680},"  4. run body executes → receives typed, instantiated objects",[363,2446,677],{"class":676},[363,2448,542],{"class":408},[716,2450],{"data":2451,"kind":719},"UGF0dGVybiBzaG93biBhYm92ZSAobm90IGV4ZWN1dGVkIGluIG5vdGVib29rIOKAlCByZXF1aXJlcyBfX21haW5fXyBndWFyZCkKCkV4ZWN1dGlvbiBmbG93OgogIDEuIHJ1bigpICAgICAgICAgICAgIOKGkiBIeWRyYSBwYXJzZXMgc3lzLmFyZ3YKICAyLiBIeWRyYSBjb21wb3NlcyAgICDihpIgYnVpbGRzIERpY3RDb25maWcgZnJvbSBjb25maWdfbmFtZSArIG92ZXJyaWRlcwogIDMuIEBMLnRhc2sgdW53cmFwcyAgIOKGkiBpbnN0YW50aWF0ZXMgZWFjaCBmaWVsZCBtYXRjaGluZyBhIHBhcmFtZXRlcgogIDQuIHJ1biBib2R5IGV4ZWN1dGVzIOKGkiByZWNlaXZlcyB0eXBlZCwgaW5zdGFudGlhdGVkIG9iamVjdHMK",[2453,2454,2456,2457],"h3",{"id":2455},"implicit-ltask","Implicit ",[231,2458,323],{},[216,2460,2461,2462,2465,2466,242,2468,2470],{},"If the function is ",[219,2463,2464],{},"not"," already wrapped with ",[231,2467,323],{},[231,2469,2249],{}," applies it implicitly. Both forms below are equivalent:",[354,2472,2474],{"className":356,"code":2473,"language":358,"meta":359,"style":359},"# Form 1: explicit @L.task + @laco.main\n# @laco.main(config_name=\"train\")\n# @L.task\n# def run_explicit(model: nn.Module, num_steps: int = 10): ...\n\n# Form 2: only @laco.main — @L.task is applied automatically\n# @laco.main(config_name=\"train\")\n# def run_implicit(model: nn.Module, num_steps: int = 10): ...\n\n# The check inside laco.main:\n# task_fn = func if getattr(func, '_laco_task', False) else _task(func)\n\n# Demonstrate the check:\n@L.task\ndef already_a_task(x: int): pass\n\ndef not_yet_a_task(x: int): pass\n\nprint(\"already_a_task._laco_task :\", getattr(already_a_task, '_laco_task', False))\nprint(\"not_yet_a_task._laco_task :\", getattr(not_yet_a_task,  '_laco_task', False))\n",[231,2475,2476,2481,2486,2490,2495,2499,2504,2508,2513,2517,2522,2527,2531,2536,2546,2567,2571,2590,2594,2630],{"__ignoreMap":359},[363,2477,2478],{"class":365,"line":366},[363,2479,2480],{"class":493},"# Form 1: explicit @L.task + @laco.main\n",[363,2482,2483],{"class":365,"line":377},[363,2484,2485],{"class":493},"# @laco.main(config_name=\"train\")\n",[363,2487,2488],{"class":365,"line":385},[363,2489,2309],{"class":493},[363,2491,2492],{"class":365,"line":392},[363,2493,2494],{"class":493},"# def run_explicit(model: nn.Module, num_steps: int = 10): ...\n",[363,2496,2497],{"class":365,"line":400},[363,2498,389],{"emptyLinePlaceholder":388},[363,2500,2501],{"class":365,"line":420},[363,2502,2503],{"class":493},"# Form 2: only @laco.main — @L.task is applied automatically\n",[363,2505,2506],{"class":365,"line":438},[363,2507,2485],{"class":493},[363,2509,2510],{"class":365,"line":642},[363,2511,2512],{"class":493},"# def run_implicit(model: nn.Module, num_steps: int = 10): ...\n",[363,2514,2515],{"class":365,"line":647},[363,2516,389],{"emptyLinePlaceholder":388},[363,2518,2519],{"class":365,"line":661},[363,2520,2521],{"class":493},"# The check inside laco.main:\n",[363,2523,2524],{"class":365,"line":667},[363,2525,2526],{"class":493},"# task_fn = func if getattr(func, '_laco_task', False) else _task(func)\n",[363,2528,2529],{"class":365,"line":688},[363,2530,389],{"emptyLinePlaceholder":388},[363,2532,2533],{"class":365,"line":693},[363,2534,2535],{"class":493},"# Demonstrate the check:\n",[363,2537,2538,2540,2542,2544],{"class":365,"line":1344},[363,2539,779],{"class":778},[363,2541,782],{"class":503},[363,2543,352],{"class":778},[363,2545,787],{"class":503},[363,2547,2548,2550,2553,2555,2558,2560,2562,2564],{"class":365,"line":1353},[363,2549,500],{"class":499},[363,2551,2552],{"class":503}," already_a_task",[363,2554,507],{"class":408},[363,2556,2557],{"class":510},"x",[363,2559,801],{"class":408},[363,2561,839],{"class":838},[363,2563,1075],{"class":408},[363,2565,2566],{"class":369}," pass\n",[363,2568,2569],{"class":365,"line":1358},[363,2570,389],{"emptyLinePlaceholder":388},[363,2572,2573,2575,2578,2580,2582,2584,2586,2588],{"class":365,"line":1364},[363,2574,500],{"class":499},[363,2576,2577],{"class":503}," not_yet_a_task",[363,2579,507],{"class":408},[363,2581,2557],{"class":510},[363,2583,801],{"class":408},[363,2585,839],{"class":838},[363,2587,1075],{"class":408},[363,2589,2566],{"class":369},[363,2591,2592],{"class":365,"line":1381},[363,2593,389],{"emptyLinePlaceholder":388},[363,2595,2596,2598,2600,2602,2605,2607,2609,2611,2613,2616,2618,2620,2622,2624,2626,2628],{"class":365,"line":1986},[363,2597,696],{"class":670},[363,2599,507],{"class":408},[363,2601,677],{"class":676},[363,2603,2604],{"class":680},"already_a_task._laco_task :",[363,2606,677],{"class":676},[363,2608,812],{"class":408},[363,2610,1004],{"class":670},[363,2612,507],{"class":408},[363,2614,2615],{"class":530},"already_a_task",[363,2617,812],{"class":408},[363,2619,1013],{"class":676},[363,2621,1016],{"class":680},[363,2623,1019],{"class":676},[363,2625,812],{"class":408},[363,2627,1025],{"class":1024},[363,2629,714],{"class":408},[363,2631,2632,2634,2636,2638,2641,2643,2645,2647,2649,2652,2654,2657,2659,2661,2663,2665],{"class":365,"line":2016},[363,2633,696],{"class":670},[363,2635,507],{"class":408},[363,2637,677],{"class":676},[363,2639,2640],{"class":680},"not_yet_a_task._laco_task :",[363,2642,677],{"class":676},[363,2644,812],{"class":408},[363,2646,1004],{"class":670},[363,2648,507],{"class":408},[363,2650,2651],{"class":530},"not_yet_a_task",[363,2653,812],{"class":408},[363,2655,2656],{"class":676},"  '",[363,2658,1016],{"class":680},[363,2660,1019],{"class":676},[363,2662,812],{"class":408},[363,2664,1025],{"class":1024},[363,2666,714],{"class":408},[716,2668],{"data":2669,"kind":719},"YWxyZWFkeV9hX3Rhc2suX2xhY29fdGFzayA6IFRydWUKbm90X3lldF9hX3Rhc2suX2xhY29fdGFzayA6IEZhbHNlCg==",[2453,2671,2673,2675],{"id":2672},"lacomain-parameters",[231,2674,2249],{}," parameters",[298,2677,2678,2691],{},[301,2679,2680],{},[304,2681,2682,2685,2688],{},[307,2683,2684],{},"Parameter",[307,2686,2687],{},"Default",[307,2689,2690],{},"Forwarded to",[314,2692,2693,2710,2727],{},[304,2694,2695,2700,2705],{},[319,2696,2697],{},[231,2698,2699],{},"config_name",[319,2701,2702],{},[231,2703,2704],{},"\"config\"",[319,2706,2707],{},[231,2708,2709],{},"@hydra.main(config_name=...)",[304,2711,2712,2717,2722],{},[319,2713,2714],{},[231,2715,2716],{},"config_path",[319,2718,2719],{},[231,2720,2721],{},"None",[319,2723,2724],{},[231,2725,2726],{},"@hydra.main(config_path=...)",[304,2728,2729,2734,2738],{},[319,2730,2731],{},[231,2732,2733],{},"version_base",[319,2735,2736],{},[231,2737,2721],{},[319,2739,2740],{},[231,2741,2742],{},"@hydra.main(version_base=...)",[216,2744,2745,2746,2749,2750,2753,2754,2757,2758,2761],{},"When ",[231,2747,2748],{},"config_path=None",", Hydra uses its own search path (config files next to the script, or on ",[231,2751,2752],{},"HYDRA_CONFIG_PATH","). For laco config files, the ",[231,2755,2756],{},"configs:\u002F\u002F"," scheme (from ",[231,2759,2760],{},"laco.handler",") provides an alternative path resolver.",[454,2763,2765],{"id":2764},"section-5-the-mnist-training-pipeline","Section 5: The MNIST training pipeline",[216,2767,2768,2769,2772,2773,2775],{},"The ",[231,2770,2771],{},"laco.examples.pipelines.mnist_train"," module is the canonical end-to-end example. Let's read its source to see ",[231,2774,323],{}," in a real pipeline:",[354,2777,2779],{"className":356,"code":2778,"language":358,"meta":359,"style":359},"import inspect\nimport laco.examples.pipelines.mnist_train as mnist\n\nprint(\"=== mnist_train.task (the @L.task entry point) ===\")\nprint(inspect.getsource(mnist.task))\n",[231,2780,2781,2787,2813,2817,2832],{"__ignoreMap":359},[363,2782,2783,2785],{"class":365,"line":366},[363,2784,370],{"class":369},[363,2786,374],{"class":373},[363,2788,2789,2791,2793,2795,2798,2800,2803,2805,2808,2810],{"class":365,"line":377},[363,2790,370],{"class":369},[363,2792,405],{"class":373},[363,2794,352],{"class":408},[363,2796,2797],{"class":411},"examples",[363,2799,352],{"class":408},[363,2801,2802],{"class":411},"pipelines",[363,2804,352],{"class":408},[363,2806,2807],{"class":411},"mnist_train",[363,2809,414],{"class":369},[363,2811,2812],{"class":373}," mnist\n",[363,2814,2815],{"class":365,"line":385},[363,2816,389],{"emptyLinePlaceholder":388},[363,2818,2819,2821,2823,2825,2828,2830],{"class":365,"line":392},[363,2820,696],{"class":670},[363,2822,507],{"class":408},[363,2824,677],{"class":676},[363,2826,2827],{"class":680},"=== mnist_train.task (the @L.task entry point) ===",[363,2829,677],{"class":676},[363,2831,542],{"class":408},[363,2833,2834,2836,2838,2840,2842,2844,2846,2849,2851,2854],{"class":365,"line":400},[363,2835,696],{"class":670},[363,2837,507],{"class":408},[363,2839,701],{"class":530},[363,2841,352],{"class":408},[363,2843,706],{"class":530},[363,2845,507],{"class":408},[363,2847,2848],{"class":530},"mnist",[363,2850,352],{"class":408},[363,2852,2853],{"class":411},"task",[363,2855,714],{"class":408},[716,2857],{"data":2858,"kind":719},"PT09IG1uaXN0X3RyYWluLnRhc2sgKHRoZSBATC50YXNrIGVudHJ5IHBvaW50KSA9PT0KQEwudGFzawpkZWYgdGFzaygKICAgIG1vZGVsOiBubi5Nb2R1bGUsCiAgICBvcHRpbWl6ZXI6IG9wdGltLk9wdGltaXplciwKICAgIGxvc3M6IG5uLk1vZHVsZSwKICAgIGxvYWRlcjogRGF0YUxvYWRlciwKICAgIG51bV9zdGVwczogaW50ID0gMSwKKSAtPiBOb25lOgogICAgIiIiUnVuIGBgbnVtX3N0ZXBzYGAgdHJhaW5pbmcgaXRlcmF0aW9ucyAoZGVmYXVsdCAxIGZvciBzbW9rZSB0ZXN0aW5nKS4KCiAgICBJbnZva2UgdmlhOjoKCiAgICAgICAgcHl0aG9uIC1tIGxhY28uZXhhbXBsZXMucGlwZWxpbmVzLm1uaXN0X3RyYWluIG51bV9zdGVwcz0yCiAgICAiIiIKCiAgICBvcHQgPSBvcHRpbWl6ZXIobW9kZWwucGFyYW1ldGVycygpKSAgIyB0eXBlOiBpZ25vcmVbb3BlcmF0b3JdCiAgICBtb2RlbC50cmFpbigpCiAgICBsb2FkZXJfaXRlciA9IGl0ZXIobG9hZGVyKQogICAgZm9yIHN0ZXAgaW4gcmFuZ2UobnVtX3N0ZXBzKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIGltYWdlcywgbGFiZWxzID0gbmV4dChsb2FkZXJfaXRlcikKICAgICAgICBleGNlcHQgU3RvcEl0ZXJhdGlvbjoKICAgICAgICAgICAgbG9hZGVyX2l0ZXIgPSBpdGVyKGxvYWRlcikKICAgICAgICAgICAgaW1hZ2VzLCBsYWJlbHMgPSBuZXh0KGxvYWRlcl9pdGVyKQogICAgICAgIG9wdC56ZXJvX2dyYWQoKQogICAgICAgIG91dCA9IG1vZGVsKGltYWdlcykKICAgICAgICBsb3NzX3ZhbCA9IGxvc3Mob3V0LCBsYWJlbHMpCiAgICAgICAgbG9zc192YWwuYmFja3dhcmQoKQogICAgICAgIG9wdC5zdGVwKCkKICAgICAgICBfID0gc3RlcCAgIyBzdXBwcmVzcyB1bnVzZWQtdmFyaWFibGUgbGludAoK",[354,2860,2862],{"className":356,"code":2861,"language":358,"meta":359,"style":359},"# Load the training sub-config (model + optimizer + loss + loader)\ncfg_train = laco.load(\"configs:\u002F\u002Fexamples\u002Fpipelines\u002Fmnist_train.py#train\")\n\nprint(\"Keys in the 'train' sub-config:\")\nfor k in cfg_train.keys():\n    print(f\"  {k}\")\n",[231,2863,2864,2869,2894,2898,2913,2934],{"__ignoreMap":359},[363,2865,2866],{"class":365,"line":366},[363,2867,2868],{"class":493},"# Load the training sub-config (model + optimizer + loss + loader)\n",[363,2870,2871,2874,2876,2878,2880,2883,2885,2887,2890,2892],{"class":365,"line":377},[363,2872,2873],{"class":373},"cfg_train ",[363,2875,523],{"class":522},[363,2877,405],{"class":373},[363,2879,352],{"class":408},[363,2881,2882],{"class":530},"load",[363,2884,507],{"class":408},[363,2886,677],{"class":676},[363,2888,2889],{"class":680},"configs:\u002F\u002Fexamples\u002Fpipelines\u002Fmnist_train.py#train",[363,2891,677],{"class":676},[363,2893,542],{"class":408},[363,2895,2896],{"class":365,"line":385},[363,2897,389],{"emptyLinePlaceholder":388},[363,2899,2900,2902,2904,2906,2909,2911],{"class":365,"line":392},[363,2901,696],{"class":670},[363,2903,507],{"class":408},[363,2905,677],{"class":676},[363,2907,2908],{"class":680},"Keys in the 'train' sub-config:",[363,2910,677],{"class":676},[363,2912,542],{"class":408},[363,2914,2915,2918,2921,2924,2927,2929,2931],{"class":365,"line":400},[363,2916,2917],{"class":369},"for",[363,2919,2920],{"class":373}," k ",[363,2922,2923],{"class":369},"in",[363,2925,2926],{"class":373}," cfg_train",[363,2928,352],{"class":408},[363,2930,195],{"class":530},[363,2932,2933],{"class":408},"():\n",[363,2935,2936,2938,2940,2942,2945,2947,2950,2952,2954],{"class":365,"line":420},[363,2937,671],{"class":670},[363,2939,507],{"class":408},[363,2941,896],{"class":499},[363,2943,2944],{"class":680},"\"  ",[363,2946,902],{"class":845},[363,2948,2949],{"class":530},"k",[363,2951,919],{"class":845},[363,2953,677],{"class":680},[363,2955,542],{"class":408},[716,2957],{"data":2958,"kind":719},"S2V5cyBpbiB0aGUgJ3RyYWluJyBzdWItY29uZmlnOgogIF90YXJnZXRfCiAgX2NvbnZlcnRfCiAgbW9kZWwKICBvcHRpbWl6ZXIKICBsb3NzCiAgbG9hZGVyCg==",[354,2960,2962],{"className":356,"code":2961,"language":358,"meta":359,"style":359},"# Instantiate only the model (cheap — no MNIST download needed)\nmodel = laco.instantiate(cfg_train.model)\nprint(\"Model type:\", type(model).__name__)\nprint(\"Model:\", model)\n",[231,2963,2964,2969,2993,3021],{"__ignoreMap":359},[363,2965,2966],{"class":365,"line":366},[363,2967,2968],{"class":493},"# Instantiate only the model (cheap — no MNIST download needed)\n",[363,2970,2971,2974,2976,2978,2980,2982,2984,2987,2989,2991],{"class":365,"line":377},[363,2972,2973],{"class":373},"model ",[363,2975,523],{"class":522},[363,2977,405],{"class":373},[363,2979,352],{"class":408},[363,2981,531],{"class":530},[363,2983,507],{"class":408},[363,2985,2986],{"class":530},"cfg_train",[363,2988,352],{"class":408},[363,2990,469],{"class":411},[363,2992,542],{"class":408},[363,2994,2995,2997,2999,3001,3004,3006,3008,3011,3013,3015,3017,3019],{"class":365,"line":385},[363,2996,696],{"class":670},[363,2998,507],{"class":408},[363,3000,677],{"class":676},[363,3002,3003],{"class":680},"Model type:",[363,3005,677],{"class":676},[363,3007,812],{"class":408},[363,3009,3010],{"class":838}," type",[363,3012,507],{"class":408},[363,3014,469],{"class":530},[363,3016,912],{"class":408},[363,3018,916],{"class":915},[363,3020,542],{"class":408},[363,3022,3023,3025,3027,3029,3032,3034,3036,3039],{"class":365,"line":392},[363,3024,696],{"class":670},[363,3026,507],{"class":408},[363,3028,677],{"class":676},[363,3030,3031],{"class":680},"Model:",[363,3033,677],{"class":676},[363,3035,812],{"class":408},[363,3037,3038],{"class":530}," model",[363,3040,542],{"class":408},[716,3042],{"data":3043,"kind":719},"TW9kZWwgdHlwZTogU2VxdWVudGlhbApNb2RlbDogU2VxdWVudGlhbCgKICAoc3RlbSk6IFNlcXVlbnRpYWwoCiAgICAoMCk6IENvbnYyZCgxLCAzMiwga2VybmVsX3NpemU9KDMsIDMpLCBzdHJpZGU9KDEsIDEpLCBwYWRkaW5nPSgxLCAxKSwgYmlhcz1GYWxzZSkKICAgICgxKTogQmF0Y2hOb3JtMmQoMzIsIGVwcz0xZS0wNSwgbW9tZW50dW09MC4xLCBhZmZpbmU9VHJ1ZSwgYmlhcz1UcnVlLCB0cmFja19ydW5uaW5nX3N0YXRzPVRydWUpCiAgICAoMik6IFJlTFUoaW5wbGFjZT1UcnVlKQogICkKICAoc3RhZ2VzKTogU2VxdWVudGlhbCgKICAgICgwKTogU2VxdWVudGlhbCgKICAgICAgKDApOiBDb252MmQoMzIsIDMyLCBrZXJuZWxfc2l6ZT0oMywgMyksIHN0cmlkZT0oMSwgMSksIHBhZGRpbmc9KDEsIDEpLCBiaWFzPUZhbHNlKQogICAgICAoMSk6IEJhdGNoTm9ybTJkKDMyLCBlcHM9MWUtMDUsIG1vbWVudHVtPTAuMSwgYWZmaW5lPVRydWUsIGJpYXM9VHJ1ZSwgdHJhY2tfcnVubmluZ19zdGF0cz1UcnVlKQogICAgICAoMik6IFJlTFUoaW5wbGFjZT1UcnVlKQogICAgICAoMyk6IE1heFBvb2wyZChrZXJuZWxfc2l6ZT0yLCBzdHJpZGU9MiwgcGFkZGluZz0wLCBkaWxhdGlvbj0xLCBjZWlsX21vZGU9RmFsc2UpCiAgICApCiAgICAoMSk6IFNlcXVlbnRpYWwoCiAgICAgICgwKTogQ29udjJkKDMyLCAzMiwga2VybmVsX3NpemU9KDMsIDMpLCBzdHJpZGU9KDEsIDEpLCBwYWRkaW5nPSgxLCAxKSwgYmlhcz1GYWxzZSkKICAgICAgKDEpOiBCYXRjaE5vcm0yZCgzMiwgZXBzPTFlLTA1LCBtb21lbnR1bT0wLjEsIGFmZmluZT1UcnVlLCBiaWFzPVRydWUsIHRyYWNrX3J1bm5pbmdfc3RhdHM9VHJ1ZSkKICAgICAgKDIpOiBSZUxVKGlucGxhY2U9VHJ1ZSkKICAgICAgKDMpOiBNYXhQb29sMmQoa2VybmVsX3NpemU9Miwgc3RyaWRlPTIsIHBhZGRpbmc9MCwgZGlsYXRpb249MSwgY2VpbF9tb2RlPUZhbHNlKQogICAgKQogICAgKDIpOiBTZXF1ZW50aWFsKAogICAgICAoMCk6IENvbnYyZCgzMiwgMzIsIGtlcm5lbF9zaXplPSgzLCAzKSwgc3RyaWRlPSgxLCAxKSwgcGFkZGluZz0oMSwgMSksIGJpYXM9RmFsc2UpCiAgICAgICgxKTogQmF0Y2hOb3JtMmQoMzIsIGVwcz0xZS0wNSwgbW9tZW50dW09MC4xLCBhZmZpbmU9VHJ1ZSwgYmlhcz1UcnVlLCB0cmFja19ydW5uaW5nX3N0YXRzPVRydWUpCiAgICAgICgyKTogUmVMVShpbnBsYWNlPVRydWUpCiAgICAgICgzKTogTWF4UG9vbDJkKGtlcm5lbF9zaXplPTIsIHN0cmlkZT0yLCBwYWRkaW5nPTAsIGRpbGF0aW9uPTEsIGNlaWxfbW9kZT1GYWxzZSkKICAgICkKICApCiAgKGhlYWQpOiBTZXF1ZW50aWFsKAogICAgKDApOiBBZGFwdGl2ZUF2Z1Bvb2wyZChvdXRwdXRfc2l6ZT0xKQogICAgKDEpOiBGbGF0dGVuKHN0YXJ0X2RpbT0xLCBlbmRfZGltPS0xKQogICAgKDIpOiBMaW5lYXIoaW5fZmVhdHVyZXM9MzIsIG91dF9mZWF0dXJlcz0xMCwgYmlhcz1UcnVlKQogICkKKQo=",[354,3045,3047],{"className":356,"code":3046,"language":358,"meta":359,"style":359},"# Run the pipeline via subprocess (shows Hydra + @L.task wiring end-to-end)\n# We use num_steps=1 for a fast smoke test (downloads MNIST if not cached)\nimport subprocess\nresult = subprocess.run(\n    [\"python\", \"-m\", \"laco.examples.pipelines.mnist_train\", \"num_steps=1\"],\n    capture_output=True, text=True,\n    cwd=\"\u002Fhome\u002Fkhwstolle\u002FProjects\u002Fresearch\u002Flaco\",\n    timeout=120,\n)\nstdout_tail = result.stdout[-600:] if result.stdout else \"\"\nstderr_tail = result.stderr[-600:] if result.stderr else \"\"\nprint(\"--- stdout ---\")\nprint(stdout_tail or \"(empty)\")\nprint(\"--- stderr ---\")\nprint(stderr_tail or \"(empty)\")\nprint(\"Return code:\", result.returncode)\n",[231,3048,3049,3054,3059,3066,3082,3123,3144,3160,3172,3176,3217,3251,3266,3286,3301,3319],{"__ignoreMap":359},[363,3050,3051],{"class":365,"line":366},[363,3052,3053],{"class":493},"# Run the pipeline via subprocess (shows Hydra + @L.task wiring end-to-end)\n",[363,3055,3056],{"class":365,"line":377},[363,3057,3058],{"class":493},"# We use num_steps=1 for a fast smoke test (downloads MNIST if not cached)\n",[363,3060,3061,3063],{"class":365,"line":385},[363,3062,370],{"class":369},[363,3064,3065],{"class":373}," subprocess\n",[363,3067,3068,3070,3072,3075,3077,3079],{"class":365,"line":392},[363,3069,1367],{"class":373},[363,3071,523],{"class":522},[363,3073,3074],{"class":373}," subprocess",[363,3076,352],{"class":408},[363,3078,284],{"class":530},[363,3080,3081],{"class":408},"(\n",[363,3083,3084,3087,3089,3091,3093,3095,3098,3101,3103,3105,3107,3109,3111,3113,3115,3118,3120],{"class":365,"line":400},[363,3085,3086],{"class":408},"    [",[363,3088,677],{"class":676},[363,3090,358],{"class":680},[363,3092,677],{"class":676},[363,3094,812],{"class":408},[363,3096,3097],{"class":676}," \"",[363,3099,3100],{"class":680},"-m",[363,3102,677],{"class":676},[363,3104,812],{"class":408},[363,3106,3097],{"class":676},[363,3108,2771],{"class":680},[363,3110,677],{"class":676},[363,3112,812],{"class":408},[363,3114,3097],{"class":676},[363,3116,3117],{"class":680},"num_steps=1",[363,3119,677],{"class":676},[363,3121,3122],{"class":408},"],\n",[363,3124,3125,3128,3130,3133,3135,3138,3140,3142],{"class":365,"line":420},[363,3126,3127],{"class":1672},"    capture_output",[363,3129,523],{"class":522},[363,3131,3132],{"class":1024},"True",[363,3134,812],{"class":408},[363,3136,3137],{"class":1672}," text",[363,3139,523],{"class":522},[363,3141,3132],{"class":1024},[363,3143,1211],{"class":408},[363,3145,3146,3149,3151,3153,3156,3158],{"class":365,"line":438},[363,3147,3148],{"class":1672},"    cwd",[363,3150,523],{"class":522},[363,3152,677],{"class":676},[363,3154,3155],{"class":680},"\u002Fhome\u002Fkhwstolle\u002FProjects\u002Fresearch\u002Flaco",[363,3157,677],{"class":676},[363,3159,1211],{"class":408},[363,3161,3162,3165,3167,3170],{"class":365,"line":642},[363,3163,3164],{"class":1672},"    timeout",[363,3166,523],{"class":522},[363,3168,3169],{"class":845},"120",[363,3171,1211],{"class":408},[363,3173,3174],{"class":365,"line":647},[363,3175,542],{"class":408},[363,3177,3178,3181,3183,3186,3188,3191,3193,3196,3199,3202,3205,3207,3209,3211,3214],{"class":365,"line":661},[363,3179,3180],{"class":373},"stdout_tail ",[363,3182,523],{"class":522},[363,3184,3185],{"class":373}," result",[363,3187,352],{"class":408},[363,3189,3190],{"class":411},"stdout",[363,3192,2184],{"class":408},[363,3194,3195],{"class":522},"-",[363,3197,3198],{"class":845},"600",[363,3200,3201],{"class":408},":]",[363,3203,3204],{"class":369}," if",[363,3206,3185],{"class":373},[363,3208,352],{"class":408},[363,3210,3190],{"class":411},[363,3212,3213],{"class":369}," else",[363,3215,3216],{"class":676}," \"\"\n",[363,3218,3219,3222,3224,3226,3228,3231,3233,3235,3237,3239,3241,3243,3245,3247,3249],{"class":365,"line":667},[363,3220,3221],{"class":373},"stderr_tail ",[363,3223,523],{"class":522},[363,3225,3185],{"class":373},[363,3227,352],{"class":408},[363,3229,3230],{"class":411},"stderr",[363,3232,2184],{"class":408},[363,3234,3195],{"class":522},[363,3236,3198],{"class":845},[363,3238,3201],{"class":408},[363,3240,3204],{"class":369},[363,3242,3185],{"class":373},[363,3244,352],{"class":408},[363,3246,3230],{"class":411},[363,3248,3213],{"class":369},[363,3250,3216],{"class":676},[363,3252,3253,3255,3257,3259,3262,3264],{"class":365,"line":688},[363,3254,696],{"class":670},[363,3256,507],{"class":408},[363,3258,677],{"class":676},[363,3260,3261],{"class":680},"--- stdout ---",[363,3263,677],{"class":676},[363,3265,542],{"class":408},[363,3267,3268,3270,3272,3274,3277,3279,3282,3284],{"class":365,"line":693},[363,3269,696],{"class":670},[363,3271,507],{"class":408},[363,3273,3180],{"class":530},[363,3275,3276],{"class":369},"or",[363,3278,3097],{"class":676},[363,3280,3281],{"class":680},"(empty)",[363,3283,677],{"class":676},[363,3285,542],{"class":408},[363,3287,3288,3290,3292,3294,3297,3299],{"class":365,"line":1344},[363,3289,696],{"class":670},[363,3291,507],{"class":408},[363,3293,677],{"class":676},[363,3295,3296],{"class":680},"--- stderr ---",[363,3298,677],{"class":676},[363,3300,542],{"class":408},[363,3302,3303,3305,3307,3309,3311,3313,3315,3317],{"class":365,"line":1353},[363,3304,696],{"class":670},[363,3306,507],{"class":408},[363,3308,3221],{"class":530},[363,3310,3276],{"class":369},[363,3312,3097],{"class":676},[363,3314,3281],{"class":680},[363,3316,677],{"class":676},[363,3318,542],{"class":408},[363,3320,3321,3323,3325,3327,3330,3332,3334,3336,3338,3341],{"class":365,"line":1358},[363,3322,696],{"class":670},[363,3324,507],{"class":408},[363,3326,677],{"class":676},[363,3328,3329],{"class":680},"Return code:",[363,3331,677],{"class":676},[363,3333,812],{"class":408},[363,3335,3185],{"class":530},[363,3337,352],{"class":408},[363,3339,3340],{"class":411},"returncode",[363,3342,542],{"class":408},[716,3344],{"data":3345,"kind":719},"LS0tIHN0ZG91dCAtLS0KKGVtcHR5KQotLS0gc3RkZXJyIC0tLQooZW1wdHkpClJldHVybiBjb2RlOiAwCg==",[454,3347,3349,3350,3352],{"id":3348},"section-6-ltask-data-flow","Section 6: ",[231,3351,323],{}," data flow",[216,3354,3355,3356,3358],{},"The complete data flow from a ",[231,3357,295],{}," to a running training function.",[298,3360,3361,3377],{},[301,3362,3363],{},[304,3364,3365,3368,3371,3374],{},[307,3366,3367],{},"Step",[307,3369,3370],{},"Input",[307,3372,3373],{},"Operation",[307,3375,3376],{},"Output",[314,3378,3379,3404,3422,3446],{},[304,3380,3381,3384,3389,3393],{},[319,3382,3383],{},"1 (at decoration)",[319,3385,3386,3388],{},[231,3387,655],{},"'s signature",[319,3390,3391],{},[231,3392,1055],{},[319,3394,3395,3396,242,3398,242,3400,242,3402],{},"Named parameters: ",[231,3397,469],{},[231,3399,472],{},[231,3401,475],{},[231,3403,479],{},[304,3405,3406,3409,3414,3419],{},[319,3407,3408],{},"2 (per call, per param)",[319,3410,3411,3413],{},[231,3412,295],{}," + param name",[319,3415,3416],{},[231,3417,3418],{},"OmegaConf.select(cfg, name)",[319,3420,3421],{},"Sub-tree for that field",[304,3423,3424,3427,3430,3434],{},[319,3425,3426],{},"3 (per call, per param)",[319,3428,3429],{},"Sub-tree",[319,3431,3432],{},[231,3433,1100],{},[319,3435,3436,3437,1105,3439,242,3442,1105,3444,249],{},"Instantiated object (e.g. ",[231,3438,469],{},[231,3440,3441],{},"nn.Module",[231,3443,472],{},[231,3445,1626],{},[304,3447,3448,3451,3454,3459],{},[319,3449,3450],{},"4 (per call)",[319,3452,3453],{},"All instantiated kwargs",[319,3455,3456],{},[231,3457,3458],{},"train(model=..., optimizer=..., loss=..., num_steps=...)",[319,3460,3461],{},"The original function body runs",[216,3463,3464,3466,3467,3469,3470,3472],{},[231,3465,472],{}," is a ",[231,3468,1626],{},", not a live optimizer — the function body still\ncalls ",[231,3471,2241],{}," to get the real object.",[454,3474,3476,3477],{"id":3475},"section-7-contrast-with-raw-hydramain","Section 7: Contrast with raw ",[231,3478,2258],{},[216,3480,3481,3482,3484,3485,3487,3488,801],{},"The value of ",[231,3483,2249],{}," + ",[231,3486,323],{}," becomes clear when you compare it with plain ",[231,3489,2258],{},[354,3491,3493],{"className":356,"code":3492,"language":358,"meta":359,"style":359},"# ============================================================\n# WITHOUT laco: raw @hydra.main — ~20 lines of boilerplate\n# ============================================================\n\n# from hydra.utils import instantiate\n# import hydra\n# from omegaconf import DictConfig\n#\n# @hydra.main(config_name=\"train\", config_path=\"configs\", version_base=None)\n# def run_hydra(cfg: DictConfig) -> None:\n#     # Every field requires a manual instantiate call\n#     model     = instantiate(cfg.model)\n#     opt_cfg   = instantiate(cfg.optimizer)          # functools.partial\n#     optimizer = opt_cfg(model.parameters())         # finish construction\n#     loss      = instantiate(cfg.loss)\n#     loader    = instantiate(cfg.dataset)            # also instantiate dataset\n#     loader    = instantiate(cfg.loader,             # and loader separately\n#                             dataset=dataset)\n#     num_steps = cfg.hps.num_steps                   # no instantiate for primitives\n#\n#     model.train()\n#     for step in range(num_steps):\n#         images, labels = next(iter(loader))\n#         loss_val = loss(model(images), labels)\n#         # ...\n#\n# if __name__ == \"__main__\":\n#     run_hydra()\n\nraw_lines = \"\"\"\n@hydra.main(config_name=\"train\", config_path=\"configs\", version_base=None)\ndef run(cfg: DictConfig) -> None:\n    model     = instantiate(cfg.model)\n    opt_cfg   = instantiate(cfg.optimizer)\n    optimizer = opt_cfg(model.parameters())\n    loss      = instantiate(cfg.loss)\n    loader    = instantiate(cfg.loader)\n    num_steps = cfg.hps.num_steps\n    # ... actual training code ...\n\"\"\"\n\n# ============================================================\n# WITH laco: @laco.main + @L.task — 5 lines\n# ============================================================\n\nlaco_lines = \"\"\"\n@laco.main(config_name=\"train\")\n@L.task\ndef run(model: nn.Module, optimizer, loss: nn.Module,\n        loader: DataLoader, num_steps: int = 10):\n    opt = optimizer(model.parameters())  # optimizer is a partial\n    # ... actual training code ...\n\"\"\"\n\nprint(\"=== Raw @hydra.main ===\")\nprint(raw_lines)\nprint(\"=== @laco.main + @L.task ===\")\nprint(laco_lines)\n",[231,3494,3495,3500,3505,3509,3513,3518,3523,3528,3532,3537,3542,3547,3552,3557,3562,3567,3572,3577,3582,3587,3591,3595,3599,3604,3609,3614,3618,3622,3627,3631,3642,3648,3654,3660,3666,3672,3678,3684,3690,3696,3702,3707,3712,3718,3723,3728,3738,3744,3750,3756,3762,3768,3773,3778,3783,3799,3811,3827],{"__ignoreMap":359},[363,3496,3497],{"class":365,"line":366},[363,3498,3499],{"class":493},"# ============================================================\n",[363,3501,3502],{"class":365,"line":377},[363,3503,3504],{"class":493},"# WITHOUT laco: raw @hydra.main — ~20 lines of boilerplate\n",[363,3506,3507],{"class":365,"line":385},[363,3508,3499],{"class":493},[363,3510,3511],{"class":365,"line":392},[363,3512,389],{"emptyLinePlaceholder":388},[363,3514,3515],{"class":365,"line":400},[363,3516,3517],{"class":493},"# from hydra.utils import instantiate\n",[363,3519,3520],{"class":365,"line":420},[363,3521,3522],{"class":493},"# import hydra\n",[363,3524,3525],{"class":365,"line":438},[363,3526,3527],{"class":493},"# from omegaconf import DictConfig\n",[363,3529,3530],{"class":365,"line":642},[363,3531,2299],{"class":493},[363,3533,3534],{"class":365,"line":647},[363,3535,3536],{"class":493},"# @hydra.main(config_name=\"train\", config_path=\"configs\", version_base=None)\n",[363,3538,3539],{"class":365,"line":661},[363,3540,3541],{"class":493},"# def run_hydra(cfg: DictConfig) -> None:\n",[363,3543,3544],{"class":365,"line":667},[363,3545,3546],{"class":493},"#     # Every field requires a manual instantiate call\n",[363,3548,3549],{"class":365,"line":688},[363,3550,3551],{"class":493},"#     model     = instantiate(cfg.model)\n",[363,3553,3554],{"class":365,"line":693},[363,3555,3556],{"class":493},"#     opt_cfg   = instantiate(cfg.optimizer)          # functools.partial\n",[363,3558,3559],{"class":365,"line":1344},[363,3560,3561],{"class":493},"#     optimizer = opt_cfg(model.parameters())         # finish construction\n",[363,3563,3564],{"class":365,"line":1353},[363,3565,3566],{"class":493},"#     loss      = instantiate(cfg.loss)\n",[363,3568,3569],{"class":365,"line":1358},[363,3570,3571],{"class":493},"#     loader    = instantiate(cfg.dataset)            # also instantiate dataset\n",[363,3573,3574],{"class":365,"line":1364},[363,3575,3576],{"class":493},"#     loader    = instantiate(cfg.loader,             # and loader separately\n",[363,3578,3579],{"class":365,"line":1381},[363,3580,3581],{"class":493},"#                             dataset=dataset)\n",[363,3583,3584],{"class":365,"line":1986},[363,3585,3586],{"class":493},"#     num_steps = cfg.hps.num_steps                   # no instantiate for primitives\n",[363,3588,3589],{"class":365,"line":2016},[363,3590,2299],{"class":493},[363,3592,3593],{"class":365,"line":2046},[363,3594,2324],{"class":493},[363,3596,3597],{"class":365,"line":2076},[363,3598,2329],{"class":493},[363,3600,3601],{"class":365,"line":2098},[363,3602,3603],{"class":493},"#         images, labels = next(iter(loader))\n",[363,3605,3606],{"class":365,"line":2103},[363,3607,3608],{"class":493},"#         loss_val = loss(model(images), labels)\n",[363,3610,3611],{"class":365,"line":2109},[363,3612,3613],{"class":493},"#         # ...\n",[363,3615,3616],{"class":365,"line":2132},[363,3617,2299],{"class":493},[363,3619,3620],{"class":365,"line":2163},[363,3621,2343],{"class":493},[363,3623,3624],{"class":365,"line":2208},[363,3625,3626],{"class":493},"#     run_hydra()\n",[363,3628,3629],{"class":365,"line":2213},[363,3630,389],{"emptyLinePlaceholder":388},[363,3632,3634,3637,3639],{"class":365,"line":3633},30,[363,3635,3636],{"class":373},"raw_lines ",[363,3638,523],{"class":522},[363,3640,3641],{"class":676}," \"\"\"\n",[363,3643,3645],{"class":365,"line":3644},31,[363,3646,3647],{"class":680},"@hydra.main(config_name=\"train\", config_path=\"configs\", version_base=None)\n",[363,3649,3651],{"class":365,"line":3650},32,[363,3652,3653],{"class":680},"def run(cfg: DictConfig) -> None:\n",[363,3655,3657],{"class":365,"line":3656},33,[363,3658,3659],{"class":680},"    model     = instantiate(cfg.model)\n",[363,3661,3663],{"class":365,"line":3662},34,[363,3664,3665],{"class":680},"    opt_cfg   = instantiate(cfg.optimizer)\n",[363,3667,3669],{"class":365,"line":3668},35,[363,3670,3671],{"class":680},"    optimizer = opt_cfg(model.parameters())\n",[363,3673,3675],{"class":365,"line":3674},36,[363,3676,3677],{"class":680},"    loss      = instantiate(cfg.loss)\n",[363,3679,3681],{"class":365,"line":3680},37,[363,3682,3683],{"class":680},"    loader    = instantiate(cfg.loader)\n",[363,3685,3687],{"class":365,"line":3686},38,[363,3688,3689],{"class":680},"    num_steps = cfg.hps.num_steps\n",[363,3691,3693],{"class":365,"line":3692},39,[363,3694,3695],{"class":680},"    # ... actual training code ...\n",[363,3697,3699],{"class":365,"line":3698},40,[363,3700,3701],{"class":676},"\"\"\"\n",[363,3703,3705],{"class":365,"line":3704},41,[363,3706,389],{"emptyLinePlaceholder":388},[363,3708,3710],{"class":365,"line":3709},42,[363,3711,3499],{"class":493},[363,3713,3715],{"class":365,"line":3714},43,[363,3716,3717],{"class":493},"# WITH laco: @laco.main + @L.task — 5 lines\n",[363,3719,3721],{"class":365,"line":3720},44,[363,3722,3499],{"class":493},[363,3724,3726],{"class":365,"line":3725},45,[363,3727,389],{"emptyLinePlaceholder":388},[363,3729,3731,3734,3736],{"class":365,"line":3730},46,[363,3732,3733],{"class":373},"laco_lines ",[363,3735,523],{"class":522},[363,3737,3641],{"class":676},[363,3739,3741],{"class":365,"line":3740},47,[363,3742,3743],{"class":680},"@laco.main(config_name=\"train\")\n",[363,3745,3747],{"class":365,"line":3746},48,[363,3748,3749],{"class":680},"@L.task\n",[363,3751,3753],{"class":365,"line":3752},49,[363,3754,3755],{"class":680},"def run(model: nn.Module, optimizer, loss: nn.Module,\n",[363,3757,3759],{"class":365,"line":3758},50,[363,3760,3761],{"class":680},"        loader: DataLoader, num_steps: int = 10):\n",[363,3763,3765],{"class":365,"line":3764},51,[363,3766,3767],{"class":680},"    opt = optimizer(model.parameters())  # optimizer is a partial\n",[363,3769,3771],{"class":365,"line":3770},52,[363,3772,3695],{"class":680},[363,3774,3776],{"class":365,"line":3775},53,[363,3777,3701],{"class":676},[363,3779,3781],{"class":365,"line":3780},54,[363,3782,389],{"emptyLinePlaceholder":388},[363,3784,3786,3788,3790,3792,3795,3797],{"class":365,"line":3785},55,[363,3787,696],{"class":670},[363,3789,507],{"class":408},[363,3791,677],{"class":676},[363,3793,3794],{"class":680},"=== Raw @hydra.main ===",[363,3796,677],{"class":676},[363,3798,542],{"class":408},[363,3800,3802,3804,3806,3809],{"class":365,"line":3801},56,[363,3803,696],{"class":670},[363,3805,507],{"class":408},[363,3807,3808],{"class":530},"raw_lines",[363,3810,542],{"class":408},[363,3812,3814,3816,3818,3820,3823,3825],{"class":365,"line":3813},57,[363,3815,696],{"class":670},[363,3817,507],{"class":408},[363,3819,677],{"class":676},[363,3821,3822],{"class":680},"=== @laco.main + @L.task ===",[363,3824,677],{"class":676},[363,3826,542],{"class":408},[363,3828,3830,3832,3834,3837],{"class":365,"line":3829},58,[363,3831,696],{"class":670},[363,3833,507],{"class":408},[363,3835,3836],{"class":530},"laco_lines",[363,3838,542],{"class":408},[716,3840],{"data":3841,"kind":719},"PT09IFJhdyBAaHlkcmEubWFpbiA9PT0KCkBoeWRyYS5tYWluKGNvbmZpZ19uYW1lPSJ0cmFpbiIsIGNvbmZpZ19wYXRoPSJjb25maWdzIiwgdmVyc2lvbl9iYXNlPU5vbmUpCmRlZiBydW4oY2ZnOiBEaWN0Q29uZmlnKSAtPiBOb25lOgogICAgbW9kZWwgICAgID0gaW5zdGFudGlhdGUoY2ZnLm1vZGVsKQogICAgb3B0X2NmZyAgID0gaW5zdGFudGlhdGUoY2ZnLm9wdGltaXplcikKICAgIG9wdGltaXplciA9IG9wdF9jZmcobW9kZWwucGFyYW1ldGVycygpKQogICAgbG9zcyAgICAgID0gaW5zdGFudGlhdGUoY2ZnLmxvc3MpCiAgICBsb2FkZXIgICAgPSBpbnN0YW50aWF0ZShjZmcubG9hZGVyKQogICAgbnVtX3N0ZXBzID0gY2ZnLmhwcy5udW1fc3RlcHMKICAgICMgLi4uIGFjdHVhbCB0cmFpbmluZyBjb2RlIC4uLgoKPT09IEBsYWNvLm1haW4gKyBATC50YXNrID09PQoKQGxhY28ubWFpbihjb25maWdfbmFtZT0idHJhaW4iKQpATC50YXNrCmRlZiBydW4obW9kZWw6IG5uLk1vZHVsZSwgb3B0aW1pemVyLCBsb3NzOiBubi5Nb2R1bGUsCiAgICAgICAgbG9hZGVyOiBEYXRhTG9hZGVyLCBudW1fc3RlcHM6IGludCA9IDEwKToKICAgIG9wdCA9IG9wdGltaXplcihtb2RlbC5wYXJhbWV0ZXJzKCkpICAjIG9wdGltaXplciBpcyBhIHBhcnRpYWwKICAgICMgLi4uIGFjdHVhbCB0cmFpbmluZyBjb2RlIC4uLgoK",[216,3843,3844],{},[219,3845,3846],{},"What laco saves you:",[726,3848,3849,3856,3864,3871],{},[729,3850,3851,3852,3855],{},"Every ",[231,3853,3854],{},"instantiate(cfg.field_name)"," call is gone: laco generates them from the signature.",[729,3857,3858,3859,3861,3862,352],{},"The function parameters are type-annotated, so pyright knows ",[231,3860,469],{}," is ",[231,3863,3441],{},[729,3865,3866,3867,3870],{},"If you add, remove, or rename a config field, only the function signature changes, not a scattered list of ",[231,3868,3869],{},"cfg.x"," accesses.",[729,3872,3873,3874,3876,3877,3879,3880,3883,3884,3887,3888,3890,3891,3893],{},"The raw ",[231,3875,2258],{}," approach also requires knowing which fields need ",[231,3878,531],{}," vs direct access (",[231,3881,3882],{},"cfg.hps.num_steps"," vs ",[231,3885,3886],{},"instantiate(cfg.model)","). ",[231,3889,323],{}," uniformly applies ",[231,3892,734],{}," to everything (which is a no-op for plain primitives).",[454,3895,3897],{"id":3896},"section-8-multirun-and-sweeps","Section 8: Multirun and sweeps",[216,3899,3900,3902,3903,242,3906,476,3909,3912],{},[231,3901,2249],{}," delegates directly to Hydra, so all of Hydra's ",[219,3904,3905],{},"multirun",[219,3907,3908],{},"sweeper",[219,3910,3911],{},"launcher"," plugins work out of the box. A single CLI invocation can launch a grid search across optimizers and learning rates:",[354,3914,3916],{"className":356,"code":3915,"language":358,"meta":359,"style":359},"# Illustrative CLI forms — not executed in this notebook.\n# They require a running Python environment with the config files available.\n\nmultirun_examples = \"\"\"\n# === Hydra multirun via @laco.main ===\n\n# Grid search: 2 optimizers × 2 learning rates = 4 runs\npython train.py -m \\\n    optimizer=sgd,adam \\\n    hps.learning_rate=1e-2,1e-3\n# Produces:\n#   run 1: optimizer=sgd,  lr=1e-2\n#   run 2: optimizer=sgd,  lr=1e-3\n#   run 3: optimizer=adam, lr=1e-2\n#   run 4: optimizer=adam, lr=1e-3\n\n# Optuna sweep (requires hydra-optuna-sweeper plugin):\npython train.py -m \\\n    hydra\u002Fsweeper=optuna \\\n    'hps.learning_rate=interval(1e-4, 1e-1)' \\\n    hydra.sweeper.n_trials=20\n\n# SLURM cluster (requires hydra-submitit-launcher plugin):\npython train.py -m \\\n    hydra\u002Flauncher=submitit_slurm \\\n    optimizer=sgd,adam \\\n    hps.learning_rate=1e-3,1e-4\n\"\"\"\n\nprint(multirun_examples)\n",[231,3917,3918,3923,3928,3932,3941,3946,3950,3955,3963,3970,3975,3980,3985,3990,3995,4000,4004,4009,4015,4022,4029,4034,4038,4043,4049,4056,4062,4067,4071,4075],{"__ignoreMap":359},[363,3919,3920],{"class":365,"line":366},[363,3921,3922],{"class":493},"# Illustrative CLI forms — not executed in this notebook.\n",[363,3924,3925],{"class":365,"line":377},[363,3926,3927],{"class":493},"# They require a running Python environment with the config files available.\n",[363,3929,3930],{"class":365,"line":385},[363,3931,389],{"emptyLinePlaceholder":388},[363,3933,3934,3937,3939],{"class":365,"line":392},[363,3935,3936],{"class":373},"multirun_examples ",[363,3938,523],{"class":522},[363,3940,3641],{"class":676},[363,3942,3943],{"class":365,"line":400},[363,3944,3945],{"class":680},"# === Hydra multirun via @laco.main ===\n",[363,3947,3948],{"class":365,"line":420},[363,3949,389],{"emptyLinePlaceholder":388},[363,3951,3952],{"class":365,"line":438},[363,3953,3954],{"class":680},"# Grid search: 2 optimizers × 2 learning rates = 4 runs\n",[363,3956,3957,3960],{"class":365,"line":642},[363,3958,3959],{"class":680},"python train.py -m ",[363,3961,3962],{"class":1024},"\\\n",[363,3964,3965,3968],{"class":365,"line":647},[363,3966,3967],{"class":680},"    optimizer=sgd,adam ",[363,3969,3962],{"class":1024},[363,3971,3972],{"class":365,"line":661},[363,3973,3974],{"class":680},"    hps.learning_rate=1e-2,1e-3\n",[363,3976,3977],{"class":365,"line":667},[363,3978,3979],{"class":680},"# Produces:\n",[363,3981,3982],{"class":365,"line":688},[363,3983,3984],{"class":680},"#   run 1: optimizer=sgd,  lr=1e-2\n",[363,3986,3987],{"class":365,"line":693},[363,3988,3989],{"class":680},"#   run 2: optimizer=sgd,  lr=1e-3\n",[363,3991,3992],{"class":365,"line":1344},[363,3993,3994],{"class":680},"#   run 3: optimizer=adam, lr=1e-2\n",[363,3996,3997],{"class":365,"line":1353},[363,3998,3999],{"class":680},"#   run 4: optimizer=adam, lr=1e-3\n",[363,4001,4002],{"class":365,"line":1358},[363,4003,389],{"emptyLinePlaceholder":388},[363,4005,4006],{"class":365,"line":1364},[363,4007,4008],{"class":680},"# Optuna sweep (requires hydra-optuna-sweeper plugin):\n",[363,4010,4011,4013],{"class":365,"line":1381},[363,4012,3959],{"class":680},[363,4014,3962],{"class":1024},[363,4016,4017,4020],{"class":365,"line":1986},[363,4018,4019],{"class":680},"    hydra\u002Fsweeper=optuna ",[363,4021,3962],{"class":1024},[363,4023,4024,4027],{"class":365,"line":2016},[363,4025,4026],{"class":680},"    'hps.learning_rate=interval(1e-4, 1e-1)' ",[363,4028,3962],{"class":1024},[363,4030,4031],{"class":365,"line":2046},[363,4032,4033],{"class":680},"    hydra.sweeper.n_trials=20\n",[363,4035,4036],{"class":365,"line":2076},[363,4037,389],{"emptyLinePlaceholder":388},[363,4039,4040],{"class":365,"line":2098},[363,4041,4042],{"class":680},"# SLURM cluster (requires hydra-submitit-launcher plugin):\n",[363,4044,4045,4047],{"class":365,"line":2103},[363,4046,3959],{"class":680},[363,4048,3962],{"class":1024},[363,4050,4051,4054],{"class":365,"line":2109},[363,4052,4053],{"class":680},"    hydra\u002Flauncher=submitit_slurm ",[363,4055,3962],{"class":1024},[363,4057,4058,4060],{"class":365,"line":2132},[363,4059,3967],{"class":680},[363,4061,3962],{"class":1024},[363,4063,4064],{"class":365,"line":2163},[363,4065,4066],{"class":680},"    hps.learning_rate=1e-3,1e-4\n",[363,4068,4069],{"class":365,"line":2208},[363,4070,3701],{"class":676},[363,4072,4073],{"class":365,"line":2213},[363,4074,389],{"emptyLinePlaceholder":388},[363,4076,4077,4079,4081,4084],{"class":365,"line":3633},[363,4078,696],{"class":670},[363,4080,507],{"class":408},[363,4082,4083],{"class":530},"multirun_examples",[363,4085,542],{"class":408},[716,4087],{"data":4088,"kind":719},"CiMgPT09IEh5ZHJhIG11bHRpcnVuIHZpYSBAbGFjby5tYWluID09PQoKIyBHcmlkIHNlYXJjaDogMiBvcHRpbWl6ZXJzIMOXIDIgbGVhcm5pbmcgcmF0ZXMgPSA0IHJ1bnMKcHl0aG9uIHRyYWluLnB5IC1tICAgICBvcHRpbWl6ZXI9c2dkLGFkYW0gICAgIGhwcy5sZWFybmluZ19yYXRlPTFlLTIsMWUtMwojIFByb2R1Y2VzOgojICAgcnVuIDE6IG9wdGltaXplcj1zZ2QsICBscj0xZS0yCiMgICBydW4gMjogb3B0aW1pemVyPXNnZCwgIGxyPTFlLTMKIyAgIHJ1biAzOiBvcHRpbWl6ZXI9YWRhbSwgbHI9MWUtMgojICAgcnVuIDQ6IG9wdGltaXplcj1hZGFtLCBscj0xZS0zCgojIE9wdHVuYSBzd2VlcCAocmVxdWlyZXMgaHlkcmEtb3B0dW5hLXN3ZWVwZXIgcGx1Z2luKToKcHl0aG9uIHRyYWluLnB5IC1tICAgICBoeWRyYS9zd2VlcGVyPW9wdHVuYSAgICAgJ2hwcy5sZWFybmluZ19yYXRlPWludGVydmFsKDFlLTQsIDFlLTEpJyAgICAgaHlkcmEuc3dlZXBlci5uX3RyaWFscz0yMAoKIyBTTFVSTSBjbHVzdGVyIChyZXF1aXJlcyBoeWRyYS1zdWJtaXRpdC1sYXVuY2hlciBwbHVnaW4pOgpweXRob24gdHJhaW4ucHkgLW0gICAgIGh5ZHJhL2xhdW5jaGVyPXN1Ym1pdGl0X3NsdXJtICAgICBvcHRpbWl6ZXI9c2dkLGFkYW0gICAgIGhwcy5sZWFybmluZ19yYXRlPTFlLTMsMWUtNAoK",[216,4090,2768,4091,4093,4094,4096,4097,4099],{},[231,4092,3100],{}," flag activates Hydra's ",[219,4095,3905],{}," mode. In this mode, Hydra expands the comma-separated values into a Cartesian product of runs (or hands them off to a configured sweeper). Each run calls ",[231,4098,323],{}," with its own config. The training script itself needs no changes.",[216,4101,4102,4103,4105],{},"This is a major advantage of building on Hydra: the same script works for single-run development ",[268,4104,741],{}," large-scale hyperparameter searches without modification.",[454,4107,4109],{"id":4108},"recap","Recap",[298,4111,4112,4122],{},[301,4113,4114],{},[304,4115,4116,4119],{},[307,4117,4118],{},"Concept",[307,4120,4121],{},"Key fact",[314,4123,4124,4143,4156,4171,4186,4200],{},[304,4125,4126,4130],{},[319,4127,4128],{},[231,4129,323],{},[319,4131,4132,4133,4136,4137,3484,4140,4142],{},"Reads ",[231,4134,4135],{},"inspect.signature","; calls ",[231,4138,4139],{},"OmegaConf.select",[231,4141,734],{}," for each named param",[304,4144,4145,4150],{},[319,4146,4147],{},[231,4148,4149],{},"wrapper._laco_task = True",[319,4151,4152,4153,4155],{},"Marker used by ",[231,4154,2249],{}," to avoid double-wrapping",[304,4157,4158,4163],{},[319,4159,4160,4162],{},[231,4161,472],{}," param type",[319,4164,4165,4167,4168,4170],{},[231,4166,1626],{},"; must call ",[231,4169,2241],{}," inside the body",[304,4172,4173,4177],{},[319,4174,4175],{},[231,4176,2249],{},[319,4178,4179,4180,4182,4183,4185],{},"Wraps ",[231,4181,2258],{},"; applies ",[231,4184,323],{}," implicitly if needed",[304,4187,4188,4191],{},[319,4189,4190],{},"Multirun",[319,4192,4193,4194,4196,4197,4199],{},"Pass ",[231,4195,3100],{}," on CLI; Hydra sweeps, ",[231,4198,2249],{}," is transparent",[304,4201,4202,4205],{},[319,4203,4204],{},"Missing required param",[319,4206,4207,4209],{},[231,4208,1118],{}," with clear message listing available keys",[216,4211,4212,229,4215,4218,4219,1140,4222,348,4225,4228],{},[219,4213,4214],{},"Next:",[231,4216,4217],{},"10.tracing.ipynb"," covers the ",[219,4220,4221],{},"tracing layer",[231,4223,4224],{},"@L.configurable",[231,4226,4227],{},"L.trace",", which let you write normal Python constructors and automatically capture them as config nodes.",[4230,4231,4232],"style",{},"html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sFwrP, html code.shiki .sFwrP{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .slqww, html code.shiki .slqww{--shiki-light:#6182B8;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .stp6e, html code.shiki .stp6e{--shiki-light:#39ADB5;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .swQdS, html code.shiki .swQdS{--shiki-light:#E53935;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":359,"searchDepth":385,"depth":385,"links":4234},[4235,4237,4239,4240,4247,4248,4250,4252,4253],{"id":456,"depth":377,"text":4236},"Section 1: The problem @L.task solves",{"id":1033,"depth":377,"text":4238},"Section 2: @L.task internals, step by step",{"id":1595,"depth":377,"text":1596},{"id":2245,"depth":377,"text":4241,"children":4242},"Section 4: @laco.main, the full Hydra app",[4243,4245],{"id":2455,"depth":385,"text":4244},"Implicit @L.task",{"id":2672,"depth":385,"text":4246},"@laco.main parameters",{"id":2764,"depth":377,"text":2765},{"id":3348,"depth":377,"text":4249},"Section 6: @L.task data flow",{"id":3475,"depth":377,"text":4251},"Section 7: Contrast with raw @hydra.main",{"id":3896,"depth":377,"text":3897},{"id":4108,"depth":377,"text":4109},"Series: laco tutorial notebooksPrerequisites: 01.why-laco.ipynb through 08.pipeline-configs.ipynb (especially 03.lazy-call-and-partial.ipynb, 04.hyperparameters-and-interpolation.ipynb, 07.typed-groups-and-schemas.ipynb)Dependencies: torch, torchvision","md",{"notebook":388},{"icon":25},{"title":55,"description":4254},"GQY7T8AJT0zXfWfcdneltkDjxtRsV--Y0prR0avRT2U",{},1785687302462]