{"entries":[{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"457-494","path":"docs/spec-compiler-part-3-dfg.md","roles":["context","applicability"],"text":"* `llvm.func` remains the sole function and ABI owner for a callable imported\n from the final linked LLVM module. `func.func` is used only for a genuinely\n standard-MLIR-native callable or helper; it cannot mirror the LLVM ABI.\n Neither callable kind chooses HostCore or AccCore ownership. Call-context\n classification decides where calls are legal.\n* `loom.spatial_region` is temporary compiler IR inside a\n `dataflow.thread`. It owns one structured graph candidate with normalized\n value, stream-channel, and memory boundary segments. It never appears in a\n finalized Canonical Dataflow Program.\n* `dataflow.thread` is the logical accelerator execution-domain\n **definition** (Symbol-bearing, module-scope, function-like). It owns the\n kernel body and one domain kind. A dense definition owns coordinate rank\n through its canonical entry-block shape; a dynamic definition designates\n one ordinary argument as its work-item payload.\n It does not itself execute; dynamic logical instances are\n materialized by one or more `dataflow.thread.launch` ops at use\n sites, then SystemMapping decides which instances occupy physical AccCore\n slots.\n* `dataflow.thread.launch` is the logical accelerator execution\n boundary. It references a `dataflow.thread` callable by symbol, supplies\n async dependencies and ordinary body operands, plus one non-negative extent\n per dense coordinate dimension. A dynamic launch instead supplies one root\n work item and no extents. Both produce one collective completion token.\n* `dataflow.work.spawn` publishes one child of the currently executing dynamic\n work item after atomically acquiring its termination responsibility. It is\n illegal in a dense thread or any graph and is not nested thread launch.\n* `dataflow.graph` is the SpatialCore leaf DFG **definition**\n (Symbol-bearing, module-scope, function-like). Its body cannot\n contain callable definitions, `llvm.call`, `func.call`,\n `dataflow.thread.launch`, `dataflow.graph.launch`, or another\n `dataflow.graph` definition.\n It is final target-independent software IR: its validity does not assert\n that any current Fabric can realize it. TechMapping owns that decision.\n* `dataflow.graph.launch` is the SpatialCore execution boundary\n inside a `dataflow.thread` definition's body. It references a\n `dataflow.graph` callable by symbol, supplies dependency events, value\n inputs, stream channel bindings, and memory imports, and yields value\n outputs, memory exports, and a trailing `done : none` result.","why":"Governing context of the sampled claim; fixes the terminology (dataflow.thread definition body, dataflow.graph callable, loom.spatial_region as the temporary candidate) and selects the dataflow.graph.launch operations of the output that the obligation ranges over."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"23-26","path":"docs/spec-compiler-part-3-dfg.md","roles":["input_construction","applicability"],"text":"the launch result is derived. Part 3 consumes each explicit\n`loom.spatial_region` inside its owning `dataflow.thread` and publishes the\ncorresponding graph definition and launch only after complete conversion and\nnative finalization succeed.","why":"Part 3 consumes each explicit loom.spatial_region inside its owning dataflow.thread and publishes the graph definition and launch; this is why the generator places every candidate region inside a thread definition and why the pass under test produces the launches."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"564-569","path":"docs/spec-compiler-part-3-dfg.md","roles":["input_construction","input_well_formedness"],"text":"6. `loom.spatial_region` is the temporary publication boundary inside an\n existing `dataflow.thread`. Its operands are normalized as value inputs,\n stream input channels, memory inputs, and stream output channels; its\n results are value outputs followed by memory outputs. Each stream input\n has one affine `source_map` from the consumer thread domain to the producer\n thread domain. The lowering collects all explicit candidates before","why":"Normalized boundary segmentation of loom.spatial_region operands (value inputs, stream input channels, memory inputs, stream output channels) and results (value then memory), plus the affine source_map per stream input; drives the operand/result segment sizes each generated region emits."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"573-574","path":"docs/spec-compiler-part-3-dfg.md","roles":["input_construction"],"text":"canonical graph. Current publication supports nested `scf.if` completion\n propagation. Stream channel segments become payload-typed graph stream","why":"Publication supports nested scf.if completion propagation, justifying the scf.if and scf.for + scf.if wrappings the generator samples around a candidate region."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"578-582,591-598","path":"docs/spec-compiler-part-3-dfg.md","roles":["input_construction","input_well_formedness"],"text":"enter the canonical graph body. One binding denotes one ordered dynamic\n event sequence. A fixed structured scope may contain multiple sequential\n or structured mutually exclusive sites. Lowering emits one fixed ordinal\n schedule, filters inactive branch sites, demuxes each input from the\n filtered ordinal, and muxes outputs back into that same dynamic order.\n Branches may have unequal or empty site sets, and a later branch selector\n may depend on an earlier input event. Enclosing loops repeatedly activate\n the same schedule, so one or several static body sites may each fire\n dynamically. Across repeated thread launches, each endpoint binding and\n logical point concatenates these per-instance sequences in deterministic\n launch issue order. Channel delivery pairs the resulting producer and\n consumer sequences by message ordinal after applying `source_map`; it does\n not pair thread activations or create activation-owned segments. Endpoint","why":"Fixed structured scopes with sequential or mutually exclusive sites and enclosing loops are in-domain inputs; bounds the generator to fixed loop/branch nesting with one endpoint site per scope."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"598-601","path":"docs/spec-compiler-part-3-dfg.md","roles":["input_well_formedness"],"text":"not pair thread activations or create activation-owned segments. Endpoint\n sites nested under `scf.parallel` or `scf.forall` have no inferred\n traversal order and fail before publication. Unselected or non-fixed\n graph-owned parallel forms also fail closed.","why":"Endpoint sites nested under scf.parallel or scf.forall fail before publication, so the generator never wraps a candidate in those forms."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"499-506","path":"docs/spec-compiler-part-3-dfg.md","roles":["input_well_formedness"],"text":"`llvm.func` or `func.func` definitions. An `llvm.call` or `func.call` inside a\n`dataflow.thread` definition's body is an InstructionCore call. If the callee\ncontains code that must become a `dataflow.graph` definition, Part 3 must\ninline or specialize that callee into the active thread definition\nbefore graph extraction. A `dataflow.thread.launch` is invalid\ntransitively inside every thread or graph definition. Non-inlined\nInstructionCore calls may remain only when their callee body is graph-free\nafter this preparation.","why":"Thread bodies that still contain graph-bearing llvm.call/func.call or a nested dataflow.thread.launch are out of the publishable domain; the generator emits neither inside thread bodies."},{"file_sha256":"d76b4cb1e888697d5f011a939e68cbc6230647c4d457c12d22689740aa43a44d","kind":"documentation_input","lines":"1413-1419","path":"docs/spec-compiler-part-3-dfg.md","roles":["input_well_formedness"],"text":"* `loom.spatial_region` is a transparent structured boundary. A blocking\n receive inside that region cannot be justified by a send that follows the\n region in the same stored-program strand merely because the published graph\n launch becomes asynchronous. Such a transformation would turn an\n inline-semantics deadlock into progress. A resulting retirement/send cycle\n therefore identifies a deadlocking or incorrectly cut candidate; lowering\n must not remove a wait by inventing a same-activation channel witness.","why":"A candidate whose blocking receive can only be justified by a send outside the region is a deadlocking cut; the generated send and receive regions are self-contained so no sampled input relies on such a witness."},{"file_sha256":"73f239de628bbf8d40145ecde732142ffcf6567c9483e6dc2286ae9176a6907c","kind":"language_definition","lines":"8-105","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 ];\n\n let hasVerifier = 1;\n}\n\n#endif // LOOM_FRONTEND_IR_LOOMOPS_TD","why":"Definition of loom.spatial_region and loom.spatial_yield: operand/result segment order, AttrSizedOperandSegments/AttrSizedResultSegments, source_maps and graph_name attributes, single-block isolated body; fixes the exact generic-form spelling the grammar emits."},{"file_sha256":"f4e60b2e62b496c3714437bd100ab5236540abebd3685dfbd25eeddb37cb7160","kind":"language_definition","lines":"973-1008","path":"include/Dataflow/IR/DataflowOps.td","roles":["context","applicability"],"text":"def Dataflow_GraphLaunchOp : Dataflow_Op<\"graph.launch\", [\n AttrSizedOperandSegments,\n AttrSizedResultSegments,\n DeclareOpInterfaceMethods\n]> {\n let summary = \"Asynchronous launch of a dataflow.graph callable\";\n let description = [{\n References a `dataflow.graph` definition by symbol from inside a\n `dataflow.thread` body. Dependencies, value inputs, stream input channel\n bindings, memory imports, and stream output channel bindings are explicit\n operand segments. Each stream input binding carries one affine\n `source_map` from the enclosing consumer thread domain to its producer\n domain. Value outputs and memory exports are SSA results; the trailing\n `done` result is the graph retirement event.\n\n The operation resolves its callee through `SymbolUserOpInterface` but does\n not project callee effects through `MemoryEffectsOpInterface`.\n }];\n\n let arguments = (ins\n FlatSymbolRefAttr:$callee,\n AffineMapArrayAttr:$source_maps,\n Variadic:$dependencies,\n Variadic:$valueInputs,\n Variadic:$streamInputs,\n Variadic:$memoryInputs,\n Variadic:$streamOutputs);\n\n let results = (outs\n Variadic:$valueResults,\n Variadic:$memoryResults,\n NoneType:$done);\n\n let hasCustomAssemblyFormat = 1;\n let hasVerifier = 1;\n}","why":"Definition of dataflow.graph.launch: operand segments (dependencies, valueInputs, streamInputs, memoryInputs, streamOutputs) and result segments (valueResults, memoryResults, trailing NoneType done); fixes the segment indices and the none-typed trailing result the postcondition reads."},{"file_sha256":"0616db64bbc547b2c92dd9801dbf1dac5136f19fc11ebdd1019ffd9660af9534","kind":"verifier","lines":"1370-1401","path":"lib/Dataflow/IR/DataflowFunctionLikeOps.cpp","roles":["input_well_formedness","context"],"text":"LogicalResult GraphLaunchOp::verify() {\n FailureOr thread = getOwningThread(getOperation());\n if (failed(thread))\n return failure();\n\n if ((*thread).getDomain().getKind() == ThreadDomainKind::DynamicWork &&\n (!getStreamInputs().empty() || !getStreamOutputs().empty()))\n return emitOpError(\n \"dynamic-work thread must not bind graph stream ports to channels\");\n\n ArrayAttr sourceMaps = getSourceMaps();\n if (sourceMaps.size() != getStreamInputs().size())\n return emitOpError(\"source_maps count (\")\n << sourceMaps.size() << \") must match stream input binding count (\"\n << getStreamInputs().size() << ')';\n\n Block &entry = thread->getBody().front();\n unsigned consumerRank =\n entry.getNumArguments() - thread->getFunctionType().getNumInputs() - 1;\n for (auto [index, attr] : llvm::enumerate(sourceMaps)) {\n AffineMap map = cast(attr).getValue();\n if (map.getNumDims() != consumerRank)\n return emitOpError(\"stream input source_map #\")\n << index << \" has \" << map.getNumDims()\n << \" dimensions but consumer thread domain has rank \"\n << consumerRank;\n if (map.getNumSymbols() != 0)\n return emitOpError(\"stream input source_map #\")\n << index << \" must not contain symbols\";\n }\n return success();\n}","why":"GraphLaunchOp::verify requires an owning thread and matches source_maps count and dimensionality to the consumer thread domain rank; confirms that a rank-0 dense thread accepts one affine_map<() -> ()> per stream input binding, which the generated stream-input candidate relies on."},{"file_sha256":"05567d70fd335a83ee2f46b2d0a3025a903207a88602a798b1845033e7f8ef64","kind":"implementation","lines":"910-919","path":"lib/Frontend/Lowering/LowerForToGraphPass.cpp","roles":["applicability"],"text":"this, \"parallel-completion-candidate-inspections\",\n \"Number of parallel completion candidates inspected for publication\"};\n\n ::llvm::StringRef getArgument() const final {\n return \"loom-lower-for-to-graph\";\n }\n ::llvm::StringRef getDescription() const final {\n return \"Publish explicit loom.spatial_region operations as \"\n \"dataflow.graph definitions plus dataflow.graph.launch ops.\";\n }","why":"Pass argument loom-lower-for-to-graph and its description (publish explicit loom.spatial_region as dataflow.graph definitions plus dataflow.graph.launch ops); evidence that the sampled stage is the producer of the constrained output construct, recorded in subject-command.json."},{"file_sha256":"7f380008fb405f6cf8d60d16d1b5980dc1d2e694f9842bcfeb6538fbcfa01099","kind":"implementation","lines":"1-12","path":"lib/Frontend/Lowering/Pipeline.cpp","roles":["applicability"],"text":"// Pipeline glue and pass-registry hooks for the SCF-to-DFG lowering\n// passes. The standard pipeline runs:\n//\n// loom-lower-for-to-graph (module-level)\n//\n// `loom-lower-for-to-graph` owns the atomic publication transaction. It\n// consumes explicit loom.spatial_region candidates, runs graph finalization\n// on a scratch module, validates the native result, and publishes only the\n// completed module. Graph memref-copy expansion is part of that finalization,\n// so a copy the current profile cannot expand fails the transaction instead of\n// reaching the published program.\n//","why":"Pipeline note that loom-lower-for-to-graph owns the atomic publication transaction at module level; supports running the single pass flag as the appropriate subject command for this claim."},{"file_sha256":"c25a72ad99349973a47f2a1e081b6b269920e25cc5f59f74619c2e7ce0c2b65d","kind":"test","lines":"1-52","path":"test/raise/scf-to-dfg-explicit-spatial-ownership.mlir","roles":["input_construction"],"text":"// RUN: loom-raise-opt --loom-lower-for-to-graph %s | FileCheck %s --implicit-check-not=@g_host_container_0 --implicit-check-not=@g_instruction_only_0\n\n// CHECK-LABEL: func.func @host_container\n// CHECK: scf.for\n// CHECK-NOT: dataflow.graph\n// CHECK: return\n\n// CHECK-LABEL: dataflow.thread private @instruction_only domain(#dataflow.thread_domain)\n// CHECK-NOT: dataflow.graph.launch\n// CHECK: memref.store\n// CHECK: dataflow.thread.yield\n\n// CHECK-LABEL: dataflow.thread private @selected_spatial domain(#dataflow.thread_domain)\n// CHECK: dataflow.graph.launch @selected_graph\n// CHECK: dataflow.thread.yield\n\n// CHECK-LABEL: dataflow.graph private @selected_graph\n// CHECK: dataflow.store\n// CHECK: dataflow.graph.return\n// CHECK-NOT: loom.spatial_region\n\nfunc.func @host_container(%target: memref<4xi32>, %value: i32) {\n %zero = arith.constant 0 : index\n %four = arith.constant 4 : index\n %one = arith.constant 1 : index\n scf.for %index = %zero to %four step %one {\n memref.store %value, %target[%index] : memref<4xi32>\n }\n return\n}\n\ndataflow.thread private @instruction_only domain(#dataflow.thread_domain)(\n %target: memref<1xi32>, %value: i32) ctrl (%ctrl: none) {\n %zero = arith.constant 0 : index\n memref.store %value, %target[%zero] : memref<1xi32>\n 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 spelling of a module with dataflow.thread definitions and one explicit loom.spatial_region carrying a value input and a memory import, run under the same single pass flag; template for the generator's thread header, ctrl argument, segment attributes, and graph_name."},{"file_sha256":"df76d22d1149cf2929b700df6f97b58d27b64d523346cfbb4dbf9ba8e66baa49","kind":"test","lines":"60-78","path":"test/raise/scf-to-dfg-nested-completion.mlir","roles":["input_construction"],"text":"//--- supported.mlir\nmodule {\n dataflow.thread private @for_completion domain(#dataflow.thread_domain)(%limit: index, %enabled: i1)\n ctrl (%start: none) {\n %c0 = arith.constant 0 : index\n %c1 = arith.constant 1 : index\n scf.for %i = %c0 to %limit step %c1 {\n scf.if %enabled {\n \"loom.spatial_region\"()\n <{operandSegmentSizes = array,\n resultSegmentSizes = array}> ({\n ^bb0:\n \"loom.spatial_yield\"()\n <{operandSegmentSizes = array}> : () -> ()\n }) {graph_name = \"for_graph\", source_maps = []} : () -> ()\n }\n }\n dataflow.thread.yield\n }","why":"Accepted spelling of a candidate region nested in scf.for and scf.if inside a dense thread, including the empty-boundary region form; used for the generator's wrapping alternatives and its no-operand region."},{"file_sha256":"3e2863717e0d5713893e5cabfb8e646c854432da0abd1478ee022ec7a610e62f","kind":"test","lines":"50-63","path":"test/raise/scf-to-dfg-atomic-publication.mlir","roles":["input_construction"],"text":"//--- channel.mlir\ndataflow.thread private @channel_sender domain(#dataflow.thread_domain)(\n %channel: !dataflow.channel, %message: i32) ctrl (%start: none) {\n \"loom.spatial_region\"(%message, %channel)\n <{operandSegmentSizes = array,\n resultSegmentSizes = array}> ({\n ^bb0(%payload: i32, %output: !dataflow.channel):\n dataflow.channel.send %output, %payload : !dataflow.channel\n \"loom.spatial_yield\"()\n <{operandSegmentSizes = array}> : () -> ()\n }) {graph_name = \"channel_graph\", source_maps = []} :\n (i32, !dataflow.channel) -> ()\n dataflow.thread.yield\n}","why":"Accepted spelling of a candidate binding one stream output channel with dataflow.channel.send inside the region and empty source_maps; used for the generator's stream-output form."},{"file_sha256":"bfda65ce4ab1fbf593346cedc9a461eaf02f9cbe97b6f04ebe63767917328c82","kind":"test","lines":"264-281","path":"test/raise/scf-to-dfg-stream-boundary.mlir","roles":["input_construction"],"text":"dataflow.thread private @stream_consumer domain(#dataflow.thread_domain)(\n %input: !dataflow.channel, %memory: memref<1xi32>)\n ctrl (%ctrl: none) {\n \"loom.spatial_region\"(%input, %memory)\n <{operandSegmentSizes = array,\n resultSegmentSizes = array}> ({\n ^bb0(%channel: !dataflow.channel, %target: memref<1xi32>):\n %message = dataflow.channel.receive %channel\n : !dataflow.channel\n %zero = arith.constant 0 : index\n memref.store %message, %target[%zero] : memref<1xi32>\n \"loom.spatial_yield\"()\n <{operandSegmentSizes = array}> : () -> ()\n }) {\n graph_name = \"consumer_graph\",\n source_maps = [affine_map<() -> ()>]\n } : (!dataflow.channel, memref<1xi32>) -> ()\n dataflow.thread.yield","why":"Accepted spelling of a stream input binding with dataflow.channel.receive and source_maps = [affine_map<() -> ()>] plus a memory import; used for the generator's stream-input form so the launch stream-input segment is exercised."}],"primary_bundle_sha256":"486f3a8b33a9aeda0bd04f5ff378d543f7271c0584f5a80467852d07e51e455b","project":"PolyArch/loom","revision":"48615bc5925ef4b9db8b4550b5d4322933cf4b7b","schema":"spectriad.authoring-context/v1","selection_sha256":"25b1dbc5743cf095b0fa2d3852c6015cab9497fcfc4f2db247928182260cc57d"}