// Input domain: one module holding one to three `dataflow.thread` definitions. // Each thread owns one or two explicit `loom.spatial_region` publication // boundaries (sequential sites in a fixed structured scope), optionally nested // in `scf.for` and/or `scf.if` completion-propagating scopes. Operands are // normalized as value inputs, stream input channels, memory inputs and stream // output channels; results are value outputs followed by memory outputs. // No `scf.parallel`/`scf.forall`, no `dataflow.thread.launch`, no calls and no // blocking receives appear inside a region, so every candidate is publishable. start: {new NTHREADS = random.randint(1, 3); new TID = 0} 'module {\n' threads '}\n'; threads: (TID < NTHREADS) thread {TID += 1} threads | (TID == NTHREADS) ''; thread: 'dataflow.thread private @thread_' tid_text ' domain(#dataflow.thread_domain)(%target: memref<4xi32>, %value: i32, %enabled: i1, %limit: index) ctrl (%start: none) {\n' ' %c_zero_' tid_text ' = arith.constant 0 : index\n' ' %c_one_' tid_text ' = arith.constant 1 : index\n' {new NSITES = random.randint(1, 2); new SID = 0} sites ' dataflow.thread.yield\n}\n'; tid_text: [str(TID)]; sfx: [str(TID) + "_" + str(SID)]; gname: ["graph_" + str(TID) + "_" + str(SID)]; sites: (SID < NSITES) site {SID += 1} sites | (SID == NSITES) ''; site: region | for_nest | if_nest | for_if_nest; for_nest: ' scf.for %iv_' sfx ' = %c_zero_' tid_text ' to %limit step %c_one_' tid_text ' {\n' region ' }\n'; if_nest: ' scf.if %enabled {\n' region ' }\n'; for_if_nest: ' scf.for %iv_' sfx ' = %c_zero_' tid_text ' to %limit step %c_one_' tid_text ' {\n' ' scf.if %enabled {\n' region ' }\n' ' }\n'; region: empty_region | memory_region | value_region; // No boundary operands and no boundary results. empty_region: ' "loom.spatial_region"()\n' ' <{operandSegmentSizes = array,\n' ' resultSegmentSizes = array}> ({\n' ' ^bb_entry:\n' ' "loom.spatial_yield"()\n' ' <{operandSegmentSizes = array}> : () -> ()\n' ' }) {graph_name = "' gname '", source_maps = []} : () -> ()\n'; // One value input and one memory input, no results. memory_region: ' "loom.spatial_region"(%value, %target)\n' ' <{operandSegmentSizes = array,\n' ' resultSegmentSizes = array}> ({\n' ' ^bb_entry(%payload_' sfx ': i32, %memory_' sfx ': memref<4xi32>):\n' ' %slot_' sfx ' = arith.constant 0 : index\n' ' memref.store %payload_' sfx ', %memory_' sfx '[%slot_' sfx '] : memref<4xi32>\n' ' "loom.spatial_yield"()\n' ' <{operandSegmentSizes = array}> : () -> ()\n' ' }) {graph_name = "' gname '", source_maps = []} : (i32, memref<4xi32>) -> ()\n'; // One value input and one value output. value_region: ' %out_' sfx ' = "loom.spatial_region"(%value)\n' ' <{operandSegmentSizes = array,\n' ' resultSegmentSizes = array}> ({\n' ' ^bb_entry(%lane_' sfx ': i32):\n' ' %sum_' sfx ' = arith.addi %lane_' sfx ', %lane_' sfx ' : i32\n' ' "loom.spatial_yield"(%sum_' sfx ')\n' ' <{operandSegmentSizes = array}> : (i32) -> ()\n' ' }) {graph_name = "' gname '", source_maps = []} : (i32) -> i32\n';