// Inputs: modules of `dataflow.thread` definitions that each own one explicit // `loom.spatial_region` publication candidate, optionally nested in fixed // structured scopes (`scf.for`, `scf.if`) that Part 3 publication supports. start: {new COUNT = random.randint(1, 3); new I = 0} 'module {\n' threads '}\n'; threads: (I < COUNT) thread_def {I += 1} threads | (I == COUNT) ''; thread_def: {new WRAP = random.randint(0, 3); new FORM = random.randint(0, 4)} ' dataflow.thread private @thread_' idx ' domain(#dataflow.thread_domain)(%value: i32, %mem: memref<4xi32>, %chan: !dataflow.channel, %flag: i1) ctrl (%start: none) {\n' ' %c0 = arith.constant 0 : index\n' ' %c1 = arith.constant 1 : index\n' ' %c4 = arith.constant 4 : index\n' wrapped ' dataflow.thread.yield\n' ' }\n'; idx: [str(I)]; wrapped: (WRAP == 0) region | (WRAP == 1) ' scf.for %i = %c0 to %c4 step %c1 {\n' region ' }\n' | (WRAP == 2) ' scf.if %flag {\n' region ' }\n' | (WRAP == 3) ' scf.for %i = %c0 to %c4 step %c1 {\n scf.if %flag {\n' region ' }\n }\n'; region: (FORM == 0) form_store | (FORM == 1) form_empty | (FORM == 2 and WRAP == 0) form_stream | (FORM == 2 and WRAP > 0) form_empty | (FORM == 3) form_value | (FORM == 4 and WRAP == 0) form_receive | (FORM == 4 and WRAP > 0) form_store; // Value input plus memory import; no boundary results. form_store: ' "loom.spatial_region"(%value, %mem)\n' ' <{operandSegmentSizes = array,\n' ' resultSegmentSizes = array}> ({\n' ' ^bb0(%payload: i32, %memory: memref<4xi32>):\n' ' %zero = arith.constant 0 : index\n' ' memref.store %payload, %memory[%zero] : memref<4xi32>\n' ' "loom.spatial_yield"()\n' ' <{operandSegmentSizes = array}> : () -> ()\n' ' }) {graph_name = "graph_' idx '", source_maps = []} :\n' ' (i32, memref<4xi32>) -> ()\n'; // Empty boundary: no inputs, no results. form_empty: ' "loom.spatial_region"()\n' ' <{operandSegmentSizes = array,\n' ' resultSegmentSizes = array}> ({\n' ' ^bb0:\n' ' "loom.spatial_yield"()\n' ' <{operandSegmentSizes = array}> : () -> ()\n' ' }) {graph_name = "graph_' idx '", source_maps = []} : () -> ()\n'; // Value input plus one stream output channel binding. form_stream: ' "loom.spatial_region"(%value, %chan)\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 = "graph_' idx '", source_maps = []} :\n' ' (i32, !dataflow.channel) -> ()\n'; // Value input and one value output. form_value: ' %sum_' idx ' = "loom.spatial_region"(%value)\n' ' <{operandSegmentSizes = array,\n' ' resultSegmentSizes = array}> ({\n' ' ^bb0(%payload: i32):\n' ' %doubled = arith.addi %payload, %payload : i32\n' ' "loom.spatial_yield"(%doubled)\n' ' <{operandSegmentSizes = array}> : (i32) -> ()\n' ' }) {graph_name = "graph_' idx '", source_maps = []} :\n' ' (i32) -> i32\n'; // One stream input channel binding with its affine `source_map`, plus a // memory import. form_receive: ' "loom.spatial_region"(%chan, %mem)\n' ' <{operandSegmentSizes = array,\n' ' resultSegmentSizes = array}> ({\n' ' ^bb0(%channel: !dataflow.channel, %target: memref<4xi32>):\n' ' %message = dataflow.channel.receive %channel : !dataflow.channel\n' ' %zero = arith.constant 0 : index\n' ' memref.store %message, %target[%zero] : memref<4xi32>\n' ' "loom.spatial_yield"()\n' ' <{operandSegmentSizes = array}> : () -> ()\n' ' }) {graph_name = "graph_' idx '", source_maps = [affine_map<() -> ()>]} :\n' ' (!dataflow.channel, memref<4xi32>) -> ()\n';