{"entries":[{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"87-100","path":"docs/spec-compiler-part-3-dfg.md","roles":["input_construction","input_well_formedness"],"text":"Between Parts 2 and 3, SCF optimization and DSE produce the selected\nStructured Program Candidate. That domain owns all performance-distinct\nstructured choices. Part 3 begins only after those choices and their typed\nownership carriers are explicit.\n\nInput to graph extraction is an MLIR module containing module-scope\n`dataflow.thread` definitions. Every selected SpatialCore candidate is already\nmaterialized as a `loom.spatial_region` inside exactly one thread. Other thread\nbody code remains InstructionCore-resident, including SCF-shaped code outside\nan explicit spatial boundary. Imported Host or InstructionCore code remains in\nits `llvm.func` envelope; genuinely standard-MLIR-native `func.func` callables\nmay coexist in the module. Either callable is ownership-neutral and does not\nauthorize graph creation through its signature, body shape, memory effects, or\nreturn convention.","why":"Normative handoff shape for Part 3 input: module-scope dataflow.thread definitions, each selected SpatialCore candidate already materialized as a loom.spatial_region in exactly one thread, InstructionCore-resident SCF outside the boundary, and ownership-neutral llvm.func / func.func callables. Drives the module skeleton, the resident-code alternative, and the prelude alternatives in candidate.pg."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"102-135","path":"docs/spec-compiler-part-3-dfg.md","roles":["applicability","context","input_construction"],"text":"Output is an initial Canonical Dataflow Program: module-level `llvm.func`\nsymbols for imported LLVM callables, any genuinely native `func.func` helpers,\nmodule-level\n`dataflow.thread` definitions reached by zero or more\n`dataflow.thread.launch` ops; and module-level `dataflow.graph`\ndefinitions reached by zero or more `dataflow.graph.launch` ops\ninside thread definitions. No `scf.*` op is left inside any\n`dataflow.graph` definition's body after successful graph-region lowering.\nThe recursive lowering contract accepts arbitrary nesting of\n`scf.if`, source-sequential `scf.for`, `scf.while`, and fixed-width\ngraph-owned `scf.parallel` or effect-form `scf.forall`. A graph-owned parallel\nop must have a compile-time fixed domain, and all facts needed to establish\nownership, width, and cross-lane legality must be present in the current\nStructured Program Candidate's semantic IR and resolved lowering config.\nThe lowerer re-proves those facts; lineage, cached analyses, and external\nprovenance cannot make an otherwise invalid candidate legal. Dynamic-width,\nresource-mapped, and result or reduction forms fail before any graph is\nmutated; the graph owner does not infer ownership, serialization, unrolling,\nor reduction order. The\n`dataflow.thread.launch` op carries the completion token and\nmapped-memory data transfer; the def remains a callable kernel\nbody, not a tensor-result returning op. Memory dependence\nconstruction runs in the recursive graph owner using basic graph-local alias\nroots and per-partition write/read frontiers (see\n`docs/spec-compiler-part-3-mem.md`).\nThe Structured Transfer Algebra defines graph-owned parallel composition only\nafter the Structured Program Candidate has materialized its P[] ownership and\nschedule form in semantic SCF. That fixed-domain SCF is the transient input\nrepresentation for mechanical lowering. It is recursively replicated into\nstatic lanes and removed; no parallel control op or schedule record survives\nin canonical graph IR.\nGraph candidate eligibility and atomic publication are governed by this\ndocument. TechMapping, SpatialMapping, and SystemMapping realization are\noutside this IR.","why":"Governing context of the sampled obligation: defines canonical graph IR (module-level dataflow.graph definitions launched from threads) that the postcondition selects, and states the accepted recursive lowering contract (arbitrary nesting of scf.if / scf.for / scf.while with fixed-width graph-owned scf.parallel or effect-form scf.forall) that the grammar samples."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"117-120","path":"docs/spec-compiler-part-3-dfg.md","roles":["input_well_formedness"],"text":"provenance cannot make an otherwise invalid candidate legal. Dynamic-width,\nresource-mapped, and result or reduction forms fail before any graph is\nmutated; the graph owner does not infer ownership, serialization, unrolling,\nor reduction order. The","why":"Dynamic-width, resource-mapped, and result/reduction parallel forms fail before any graph is mutated; the grammar therefore only emits compile-time constant lane domains, effect-form scf.forall, and scf.parallel with an empty scf.reduce."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"1454-1461","path":"docs/spec-compiler-part-3-dfg.md","roles":["input_construction","input_well_formedness"],"text":"This section records Dataflow templates for SCF boundaries. Recursive lowering\napplies the same transfer to `scf.if`, normalized `scf.index_switch`,\nsource-sequential `scf.for`, `scf.while`, and fixed-domain\neffect-form `scf.parallel` / `scf.forall`. A zero-case `scf.index_switch` is\nreplaced by its default region during structured normalization. Other\nunsupported source forms must be normalized by Part 2 before handoff of the\nselected Structured Program Candidate and are rejected if they remain in a\ngraph.","why":"Enumerates the SCF boundary forms the recursive transfer accepts inside a graph candidate and states that other source forms must have been normalized before handoff; bounds the nesting alternatives sampled by the grammar."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"2140-2171","path":"docs/spec-compiler-part-3-dfg.md","roles":["context","input_construction"],"text":"For an accepted one-dimensional effect-form loop, `%N` denotes a\ncompile-time-resolved extent and the candidate has already selected\n`P[] = [%N]`:\n\n```mlir\nscf.parallel (%i) = (%c0) to (%N) step (%c1) {\n %x = memref.load %A[%i] : memref\n %y = arith.mulf %x, %x : f32\n memref.store %y, %B[%i] : memref\n scf.reduce\n}\n```\n\n`scf.parallel` is not a second Dataflow loop primitive. No\n`dataflow.parallel`, `dataflow.reduce`, reduction enum, schedule record, or\nparallel control op is introduced.\n\n#### Parallel Boundary Translation\n\nFor rank `r` and fixed widths `P[]`, the graph owner creates one static lane\nfor each logical coordinate tuple in the selected Cartesian domain. Each lane\nstarts from the same incoming execution and per-partition `(W, R)` frontier,\nsubstitutes its already selected source induction values, and recursively\nlowers the existing body. Incomparable exits are joined with fixed-arity\nall-of; an empty domain is an identity transfer. The Cartesian rank is not\nbounded by this lowering contract.\n\nLane enumeration is an implementation detail and never creates\ncross-iteration program order. A failed independence or ownership re-proof\ncauses atomic failure. No parallel boundary, coordinate tuple, `P[]` record,\ndependence summary, or traversal order survives into canonical graph IR.","why":"Terminology for the sampled obligation: the fixed-domain scf.parallel template for an already-selected P[], and the statement that no dataflow.parallel, dataflow.reduce, reduction enum, schedule record, or parallel control op is introduced and no parallel boundary or P[] record survives into canonical graph IR. Fixes what 'parallel control op' and 'schedule record' name in this IR."},{"file_sha256":"30c9c0c7b66af358b2cbdbeed35564e3c71f3e3dbcd88fa3a901229479c606b1","kind":"implementation","lines":"24-65","path":"include/Frontend/Lowering/Passes.h","roles":["applicability"],"text":"// transaction succeeds.\n//\n// Published graph symbols are deterministic, collision-free, and\n// construction-local. graph_name may supply a readability/debug stem; symbol\n// spelling is not ownership, graph identity, or artifact identity.\nstd::unique_ptr<::mlir::Pass> createLowerForToGraphPass();\n\n// Module-scope pass that expands SpatialCore-owned `memref.copy` inside\n// dataflow.graph bodies into a structured memref.load/memref.store element\n// loop. The graph-memory owner then derives the ordinary dataflow.load/store\n// pair and its ctrl/done network, so the canonical program keeps no bulk\n// transfer op. A copy outside the supported profile fails here, inside the\n// publication transaction.\nstd::unique_ptr<::mlir::Pass> createExpandGraphMemrefCopyPass();\n\n// Module-scope owner for graph-local memory and structured regions. It\n// normalizes supported scalar LLVM and memref accesses to dataflow.load/store,\n// computes basic graph-local alias-root partitions, and recursively lowers\n// scf.if/scf.for/scf.while while carrying execution, values, and independent\n// write/read frontiers. Raw parallel SCF fails before mutation.\nstd::unique_ptr<::mlir::Pass> createLowerGraphMemoryPass();\n\n// Module-scope pass that promotes each used `arith.constant` op inside a\n// dataflow.graph body into a `dataflow.constant` op driven by the body's\n// leading `thread_ctrl` block argument. Graph-local scalar literals therefore\n// remain visible to PnR as configurable hardware constants, including literals\n// feeding scalar arithmetic, structured loop bounds, or streaming primitives.\nstd::unique_ptr<::mlir::Pass> createLowerGraphConstantsPass();\n\n// Register the lowering passes with the global pass registry so\n// loom-raise-opt can drive them via --loom-lower-forall-to-thread /\n// --loom-lower-for-to-graph / --loom-expand-graph-memref-copy /\n// --loom-lower-graph-memory / --loom-lower-graph-constants plus the combined\n// --loom-lower-scf-to-dfg pipeline.\nvoid registerLoweringPasses();\n\n// Append the SCF-to-DFG lowering pipeline to the given pass manager:\n// loom-lower-for-to-graph (module-level)\n// The for-to-graph publisher internally owns canonicalization, graph\n// memref-copy expansion, graph memory/control lowering, constant promotion,\n// and native validation.\nvoid buildLoweringPipeline(::mlir::PassManager &pm);","why":"Identifies --loom-lower-scf-to-dfg as the combined SCF-to-DFG pipeline built from the module-level for-to-graph publisher (which internally owns canonicalization, graph memory/control lowering, constant promotion, and native validation). Evidence that the supplied stage flag is the one that publishes graphs and removes parallel SCF; no stage attribution mismatch."},{"file_sha256":"73f239de628bbf8d40145ecde732142ffcf6567c9483e6dc2286ae9176a6907c","kind":"language_definition","lines":"8-101","path":"include/Frontend/IR/LoomOps.td","roles":["input_construction","input_well_formedness"],"text":"def Loom_SpatialRegionOp : Loom_Op<\"spatial_region\", [\n IsolatedFromAbove,\n SingleBlock,\n AttrSizedOperandSegments,\n AttrSizedResultSegments,\n RecursiveMemoryEffects\n]> {\n let summary = \"Structured candidate for one SpatialCore graph\";\n let description = [{\n Holds one structured candidate inside a `dataflow.thread`. Operands are\n normalized as value inputs, stream input channels, memory inputs, and\n stream output channels. Results are normalized as value outputs followed\n by memory outputs. Each stream input has one affine `source_map`.\n\n This operation is temporary compiler IR. Successful publication replaces\n it with one native-valid `dataflow.graph` and its matching launch.\n }];\n\n let arguments = (ins\n Variadic:$valueInputs,\n Variadic:$streamInputs,\n Variadic:$memoryInputs,\n Variadic:$streamOutputs,\n AffineMapArrayAttr:$source_maps,\n OptionalAttr:$graph_name);\n\n let results = (outs\n Variadic:$valueResults,\n Variadic:$memoryResults);\n\n let regions = (region AnyRegion:$body);\n\n let skipDefaultBuilders = 1;\n let builders = [\n OpBuilder<(ins\n \"::mlir::ValueRange\":$valueInputs,\n \"::mlir::ValueRange\":$streamInputs,\n \"::mlir::ValueRange\":$memoryInputs,\n \"::mlir::ValueRange\":$streamOutputs,\n \"::mlir::TypeRange\":$valueResultTypes,\n \"::mlir::TypeRange\":$memoryResultTypes,\n \"::mlir::ArrayAttr\":$sourceMaps,\n CArg<\"::mlir::StringAttr\", \"{}\">:$graphName), [{\n $_state.addOperands(valueInputs);\n $_state.addOperands(streamInputs);\n $_state.addOperands(memoryInputs);\n $_state.addOperands(streamOutputs);\n $_state.addTypes(valueResultTypes);\n $_state.addTypes(memoryResultTypes);\n $_state.addAttribute(\"source_maps\", sourceMaps);\n if (graphName)\n $_state.addAttribute(\"graph_name\", graphName);\n auto &properties = $_state.getOrAddProperties();\n properties.operandSegmentSizes = {\n static_cast(valueInputs.size()),\n static_cast(streamInputs.size()),\n static_cast(memoryInputs.size()),\n static_cast(streamOutputs.size())};\n properties.resultSegmentSizes = {\n static_cast(valueResultTypes.size()),\n static_cast(memoryResultTypes.size())};\n $_state.addRegion();\n }]>\n ];\n\n let hasVerifier = 1;\n}\n\ndef Loom_SpatialYieldOp : Loom_Op<\"spatial_yield\", [\n Terminator,\n ParentOneOf<[\"::loom::SpatialRegionOp\"]>,\n AttrSizedOperandSegments,\n Pure\n]> {\n let summary = \"Yield value and memory results from a spatial candidate\";\n\n let arguments = (ins\n Variadic:$values,\n Variadic:$memories);\n\n let skipDefaultBuilders = 1;\n let builders = [\n OpBuilder<(ins\n \"::mlir::ValueRange\":$values,\n \"::mlir::ValueRange\":$memories), [{\n $_state.addOperands(values);\n $_state.addOperands(memories);\n auto &properties = $_state.getOrAddProperties();\n properties.operandSegmentSizes = {\n static_cast(values.size()),\n static_cast(memories.size())};\n }]>\n ];","why":"Operand/result segmentation (valueInputs, streamInputs, memoryInputs, streamOutputs), source_maps and graph_name attributes of loom.spatial_region, and the loom.spatial_yield terminator; fixes the exact generic-form spelling the grammar emits for each spatial candidate."},{"file_sha256":"f4e60b2e62b496c3714437bd100ab5236540abebd3685dfbd25eeddb37cb7160","kind":"language_definition","lines":"614-676","path":"include/Dataflow/IR/DataflowOps.td","roles":["input_construction","input_well_formedness"],"text":"def Dataflow_ThreadOp : Dataflow_Op<\"thread\", [\n AutomaticAllocationScope,\n IsolatedFromAbove,\n HasParent<\"::mlir::ModuleOp\">,\n SingleBlockImplicitTerminator<\"ThreadYieldOp\">,\n FunctionOpInterface,\n RecursiveMemoryEffects\n]> {\n let summary = \"Symbol-bearing function-like AccCore kernel definition\";\n let description = [{\n Module-scope, function-like callable that holds an AccCore kernel\n body. It does not itself execute; one or more\n `dataflow.thread.launch` ops materialize launches of it.\n\n The body's entry block has the layout\n `(args_*, thread_ctrl: none, iv_*: index)` (per spec section\n 5.4.1). The first N block args mirror `function_type.inputs`; the\n trailing `thread_ctrl` and grid index args are NOT in\n `function_type` (they are launch-instance extras). Specifically:\n\n * Args[0 .. N-1] match `function_type.inputs` position-wise.\n * Args[N] is `none` -- the per-launch `thread_ctrl`\n slot, used as the AccCore start signal and\n consumed by root `dataflow.graph.launch` ops\n in the body as a dependency event.\n * Args[N+1 .. end] are all `index` -- one per grid dim.\n\n The custom assembly format prints the required `domain(...)` immediately\n after the symbol and the trailing extras after the function-style\n signature using a separate `ctrl ( ... )` clause\n (the `thread_ctrl` slot) and an `iv ( ... )` clause (the\n grid-index slots). Either / both clauses are optional; threads\n written without them are accepted at parse time only when the op\n is external (i.e., body is empty), since a body-having thread\n must carry the trailing `thread_ctrl` slot per the verifier.\n\n The op is `IsolatedFromAbove`; values flow in only through the\n matching `dataflow.thread.launch` body operands.\n\n Every definition carries one closed `domain`: DenseRectangular or\n DynamicWork. Dense rank is derived solely from the trailing index block\n arguments. DynamicWork carries one ordinary function-input ordinal and has\n no coordinate suffix.\n }];\n\n let arguments = (ins\n SymbolNameAttr:$sym_name,\n TypeAttrOf:$function_type,\n Dataflow_ThreadDomainAttr:$domain,\n OptionalAttr:$sym_visibility,\n OptionalAttr:$arg_attrs,\n OptionalAttr:$res_attrs);\n\n let regions = (region SizedRegion<1>:$body);\n\n let hasCustomAssemblyFormat = 1;\n let hasVerifier = 1;\n\n let builders = [\n OpBuilder<(ins\n \"::llvm::StringRef\":$name,\n \"::mlir::FunctionType\":$type,\n \"::dataflow::ThreadDomainAttr\":$domain,","why":"dataflow.thread definition: module-scope symbol, required domain attribute, and the entry-block layout (args_*, thread_ctrl: none, iv_*) printed with the ctrl(...) clause; fixes the thread header the grammar emits."},{"file_sha256":"f4e60b2e62b496c3714437bd100ab5236540abebd3685dfbd25eeddb37cb7160","kind":"language_definition","lines":"839-860","path":"include/Dataflow/IR/DataflowOps.td","roles":["context"],"text":"def Dataflow_GraphOp : Dataflow_Op<\"graph\", [\n IsolatedFromAbove,\n HasParent<\"::mlir::ModuleOp\">,\n SingleBlockImplicitTerminator<\"GraphReturnOp\">,\n FunctionOpInterface,\n RecursiveMemoryEffects,\n DeclareOpInterfaceMethods\n]> {\n let summary = \"Symbol-bearing function-like SpatialCore graph definition\";\n let description = [{\n Module-scope, function-like callable holding the SpatialCore body\n of a leaf dataflow graph. It does not itself execute; one or more\n `dataflow.graph.launch` ops materialise launches of it inside the\n body of a `dataflow.thread` definition.\n\n `function_type` contains only application payload ports. Normalized\n `input_segments` and `result_segments` classify those payloads as value,\n stream, and memory ports. The body's distinguished leading `none` block\n argument is the invocation start protocol endpoint, while launch `done`\n is derived exclusively from `dataflow.graph.return.complete`; neither is\n stored in the function type.","why":"dataflow.graph op definition; fixes the operation name used to select canonical graph definitions in the postcondition."},{"file_sha256":"320a66521bba7346cf97dce9b11dce757385efbfbe7c36cc03f44198965edb4b","kind":"verifier","lines":"125-165","path":"lib/Frontend/Lowering/GraphParallelLowering.cpp","roles":["input_well_formedness"],"text":"return std::nullopt;\n result.push_back(*constant);\n }\n return result;\n}\n\nstd::optional\ngetFixedParallelDomain(::mlir::scf::ForallOp forall) {\n auto lower = getConstantIndices(forall.getMixedLowerBound());\n auto upper = getConstantIndices(forall.getMixedUpperBound());\n auto step = getConstantIndices(forall.getMixedStep());\n if (!lower || !upper || !step)\n return std::nullopt;\n return FixedParallelDomain{std::move(*lower), std::move(*upper),\n std::move(*step)};\n}\n\nstd::optional\ngetFixedParallelDomain(::mlir::scf::ParallelOp parallel) {\n FixedParallelDomain domain;\n for (::mlir::Value value : parallel.getLowerBound()) {\n auto constant = getConstantIndex(value);\n if (!constant)\n return std::nullopt;\n domain.lower.push_back(*constant);\n }\n for (::mlir::Value value : parallel.getUpperBound()) {\n auto constant = getConstantIndex(value);\n if (!constant)\n return std::nullopt;\n domain.upper.push_back(*constant);\n }\n for (::mlir::Value value : parallel.getStep()) {\n auto constant = getConstantIndex(value);\n if (!constant)\n return std::nullopt;\n domain.step.push_back(*constant);\n }\n return domain;\n}","why":"getFixedParallelDomain for scf.forall and scf.parallel requires constant lower/upper/step; establishes that the generated lane domains must be arith.constant-backed for the candidate to be accepted rather than rejected before mutation."},{"file_sha256":"320a66521bba7346cf97dce9b11dce757385efbfbe7c36cc03f44198965edb4b","kind":"verifier","lines":"1359-1425","path":"lib/Frontend/Lowering/GraphParallelLowering.cpp","roles":["input_well_formedness","context"],"text":"::mlir::LogicalResult\ncheckParallelPreconditions(::llvm::ArrayRef<::mlir::Operation *> parallelOps,\n bool requireFixedDomain, bool selectedOwnership) {\n if (parallelOps.empty())\n return ::mlir::success();\n\n ::llvm::DenseMap<::mlir::Operation *, ParallelCheckInfo> checks;\n ::llvm::DenseSet<::mlir::Operation *> provenParallelOps;\n for (::mlir::Operation *op : parallelOps) {\n if (op->hasAttr(\"loom.parallel_group\") ||\n op->hasAttr(\"loom.parallel_schedule\"))\n return op->emitError(\n \"loom-lower-graph-memory: parallel SCF carries unsupported author \"\n \"metadata\");\n\n if (auto mapping = op->getAttrOfType<::mlir::ArrayAttr>(\"mapping\");\n mapping && !mapping.empty())\n return op->emitError(\n \"loom-lower-graph-memory: graph-owned parallel SCF must not retain \"\n \"an execution-resource mapping\");\n\n if (auto forall = ::llvm::dyn_cast<::mlir::scf::ForallOp>(op)) {\n auto inParallel = forall.getTerminator();\n if (!forall.getOutputs().empty() || forall.getNumResults() != 0 ||\n inParallel.getRegion().empty() ||\n !inParallel.getRegion().front().empty())\n return forall.emitError(\n \"loom-lower-graph-memory: graph-owned scf.forall must be in \"\n \"effect form before fixed-lane lowering\");\n } else {\n auto parallel = ::mlir::cast<::mlir::scf::ParallelOp>(op);\n auto reduce = ::mlir::cast<::mlir::scf::ReduceOp>(\n parallel.getBody()->getTerminator());\n if (!parallel.getInitVals().empty() || parallel.getNumResults() != 0 ||\n !reduce.getOperands().empty() || !reduce.getReductions().empty())\n return parallel.emitError(\n \"loom-lower-graph-memory: graph-owned scf.parallel reductions \"\n \"must be normalized before fixed-lane lowering\");\n }\n\n std::optional domain;\n if (auto forall = ::llvm::dyn_cast<::mlir::scf::ForallOp>(op))\n domain = getFixedParallelDomain(forall);\n else if (auto parallel = ::llvm::dyn_cast<::mlir::scf::ParallelOp>(op))\n domain = getFixedParallelDomain(parallel);\n if (requireFixedDomain && !domain)\n return op->emitError(\n \"loom-lower-graph-memory: selected graph-owned parallel SCF \"\n \"requires a fixed compile-time lane domain\");\n if (domain &&\n ::llvm::any_of(domain->step, [](int64_t step) { return step <= 0; }))\n return op->emitError(\n \"loom-lower-graph-memory: selected graph-owned parallel SCF \"\n \"requires positive fixed lane steps\");\n\n bool graphOwned =\n static_cast(op->getParentOfType<::dataflow::GraphOp>());\n checks.try_emplace(op, ParallelCheckInfo{op,\n std::move(domain),\n selectedOwnership || graphOwned ||\n hasSpatialCarrierAncestor(op),\n {},\n nullptr});\n provenParallelOps.insert(op);\n }\n\n ::mlir::Operation *root = parallelOps.front();","why":"checkParallelPreconditions rejects parallel SCF carrying loom.parallel_group / loom.parallel_schedule author metadata or a non-empty mapping array, and requires effect-form scf.forall and reduction-free scf.parallel. Fixes both the accepted input spelling and the concrete attribute names that a surviving schedule record would use."},{"file_sha256":"dcb708e61fd42fa8e3f9a37ef7669b0fbd5b19123b648d5d66dd735b763e018d","kind":"test","lines":"18-41","path":"test/raise/scf-to-dfg-graph-owned-parallel-recurrence.mlir","roles":["input_construction"],"text":"// CHECK-NOT: scf.\n// CHECK: dataflow.graph.return\n\ndataflow.thread private @parallel_recurrence domain(#dataflow.thread_domain)(\n %n: index, %memory: memref) ctrl (%ctrl: none) {\n \"loom.spatial_region\"(%n, %memory)\n <{operandSegmentSizes = array,\n resultSegmentSizes = array}> ({\n ^bb0(%limit: index, %target: memref):\n %zero = arith.constant 0 : index\n %one = arith.constant 1 : index\n scf.forall (%lane) in (2) {\n %sum = scf.for %i = %zero to %limit step %one\n iter_args(%state = %lane) -> (index) {\n %next = arith.addi %state, %i : index\n scf.yield %next : index\n }\n memref.store %sum, %target[%lane] : memref\n }\n \"loom.spatial_yield\"()\n <{operandSegmentSizes = array}> : () -> ()\n }) {graph_name = \"g_parallel_recurrence_0\", source_maps = []} :\n (index, memref) -> ()\n dataflow.thread.yield","why":"Accepted spelling of a dataflow.thread holding a loom.spatial_region whose body is a fixed-width scf.forall with nested scf.for; models the grammar's thread/region/parallel nesting."},{"file_sha256":"c25a72ad99349973a47f2a1e081b6b269920e25cc5f59f74619c2e7ce0c2b65d","kind":"test","lines":"36-52","path":"test/raise/scf-to-dfg-explicit-spatial-ownership.mlir","roles":["input_construction"],"text":"dataflow.thread.yield\n}\n\ndataflow.thread private @selected_spatial domain(#dataflow.thread_domain)(\n %target: memref<1xi32>, %value: i32) ctrl (%ctrl: none) {\n \"loom.spatial_region\"(%value, %target)\n <{operandSegmentSizes = array,\n resultSegmentSizes = array}> ({\n ^bb0(%payload: i32, %memory: memref<1xi32>):\n %zero = arith.constant 0 : index\n memref.store %payload, %memory[%zero] : memref<1xi32>\n \"loom.spatial_yield\"()\n <{operandSegmentSizes = array}> : () -> ()\n }) {graph_name = \"selected_graph\", source_maps = []} :\n (i32, memref<1xi32>) -> ()\n dataflow.thread.yield\n}","why":"Accepted generic-form spelling of loom.spatial_region with operandSegmentSizes / resultSegmentSizes, graph_name and source_maps, plus loom.spatial_yield and dataflow.thread.yield; copied structurally by the grammar."},{"file_sha256":"91580d3883ebdf55b76d5adca6caa06d3e823f9e0b5114dfd795e16c185c3ec1","kind":"test","lines":"12-30,78-100","path":"test/raise/scf-to-dfg-memory-frontier-parallel.mlir","roles":["input_construction","input_well_formedness"],"text":"dataflow.graph private @repeat_parallel(\n %start: none, %limit: index, %memory: memref) -> ()\n attributes {input_segments = array,\n result_segments = array} {\n %c0 = arith.constant 0 : index\n %c1 = arith.constant 1 : index\n %c2 = arith.constant 2 : index\n scf.for %outer = %c0 to %limit step %c1 {\n scf.parallel (%lane) = (%c0) to (%c2) step (%c1) {\n %index = arith.addi %outer, %lane : index\n %value = memref.load %memory[%index] : memref\n scf.reduce\n }\n }\n dataflow.graph.return %start : none\n}\n\n// Branch-local parallel joins must precede the outer selected frontier.\n// CHECK-LABEL: dataflow.graph private @select_parallel(\n// dimensions. Descendant lane coordinates remain independent during an\n// ancestor proof.\n// CHECK-LABEL: dataflow.graph private @nested_parallel_matrix(\n// CHECK-COUNT-4: dataflow.store\n// CHECK-NOT: scf.\n// CHECK: dataflow.graph.return\ndataflow.graph private @nested_parallel_matrix(\n %start: none, %memory: memref<2x2xi32>) -> ()\n attributes {input_segments = array,\n result_segments = array} {\n %c0 = arith.constant 0 : index\n %c1 = arith.constant 1 : index\n %c2 = arith.constant 2 : index\n %value = arith.constant 7 : i32\n scf.parallel (%i) = (%c0) to (%c2) step (%c1) {\n scf.parallel (%j) = (%c0) to (%c2) step (%c1) {\n memref.store %value, %memory[%i, %j] : memref<2x2xi32>\n scf.reduce\n }\n scf.reduce\n }\n dataflow.graph.return %start : none\n}","why":"Accepted fixed-domain scf.parallel spelling with a trailing scf.reduce, a parallel nested inside a sequential scf.for, and a lane-disjoint nested parallel-in-parallel form; guides the lane-indexed stores that keep the generated candidates legal."},{"file_sha256":"a30ba020ae6f3ea80191d996f787ba463974694f0e0032b5323072e7538cb5d7","kind":"test","lines":"1-10","path":"test/raise/scf-to-dfg-pipeline.mlir","roles":["applicability"],"text":"// RUN: loom-raise-opt --loom-lower-scf-to-dfg %s | FileCheck %s\n\n// The production pipeline does not infer thread ownership for an unmapped\n// host forall. It publishes only explicit loom.spatial_region operations\n// already nested in dataflow.thread definitions.\n\n// CHECK-LABEL: func.func @vecadd_like\n// CHECK: scf.forall\n// CHECK-NOT: dataflow.thread.launch @t_vecadd_like_0\n// CHECK-NOT: dataflow.thread.launch @t_vecadd_like_red","why":"Shows loom-raise-opt --loom-lower-scf-to-dfg driven over a module and that graphs are published only from explicit loom.spatial_region ops already nested in dataflow.thread definitions; confirms the subject invocation and why the grammar never relies on unmapped host SCF."}],"primary_bundle_sha256":"7ad676ea93f5d6cedff5da948eb05a79108b48381eb246e9b66a9b57fa0f9959","project":"PolyArch/loom","revision":"48615bc5925ef4b9db8b4550b5d4322933cf4b7b","schema":"spectriad.authoring-context/v1","selection_sha256":"880fa4fba504a817a777dd5c5d5ae12f06777550dbe8062388b85c65f96675d6"}