The complete ASL owner is shown directly below.
12
345678910111213
14pure func BundleLocalGenerationSlot(hand: integer {0..3},15 participant_mask: bits(4))16 => integer {0..63}17begin18 return (hand + UInt(participant_mask) * 4) as integer {0..63};19end;20
21readonly func BundleLocalGenerationOpenForDifferentMask(22 hand: integer {0..3}, participant_mask: bits(4)) => boolean23begin24 for mask_value = 1 to 15 do25 let candidate_mask = Zeros{4} + mask_value;26 if candidate_mask != participant_mask &&27 _LocalGenerations[[BundleLocalGenerationSlot(28 hand, candidate_mask)]].open then29 return TRUE;30 end;31 end;32 return FALSE;33end;34
35readonly func BundleLocalGenerationOpenForHand(36 hand: integer {0..3}) => boolean37begin38 for mask_value = 1 to 15 do39 let candidate_mask = Zeros{4} + mask_value;40 if _LocalGenerations[[BundleLocalGenerationSlot(41 hand, candidate_mask)]].open then42 return TRUE;43 end;44 end;45 return FALSE;46end;47
48func ClearBundleLocalGenerationState(slot: integer {0..63})49begin50 _LocalGenerations[[slot]].open = FALSE;51 _LocalGenerations[[slot]].closed = FALSE;52 _LocalGenerations[[slot]].published = FALSE;53 _LocalGenerations[[slot]].destination_hand = 0;54 _LocalGenerations[[slot]].participant_mask = Zeros{4};55 _LocalGenerations[[slot]].generation_instance = Zeros{PTO_XLEN};56 _LocalGenerations[[slot]].init_tpc = Zeros{PTO_XLEN};57 _LocalGenerations[[slot]].init_tpc_valid = FALSE;58 _LocalGenerations[[slot]].parent_size_code = 0;59 _LocalGenerations[[slot]].parent_cell_count = 0;60 _LocalGenerations[[slot]].parent_descriptor.valid = FALSE;61 _LocalGenerations[[slot]].parent_descriptor.object_name = 0;62 _LocalGenerations[[slot]].parent_descriptor.object_kind = TileStorage_Numeric;63 _LocalGenerations[[slot]].parent_descriptor.participant_mask = Zeros{4};64 _LocalGenerations[[slot]].parent_descriptor.capacity_bytes = 0;65 _LocalGenerations[[slot]].parent_descriptor.rows = 0;66 _LocalGenerations[[slot]].parent_descriptor.columns = 0;67 _LocalGenerations[[slot]].parent_descriptor.valid_rows = 0;68 _LocalGenerations[[slot]].parent_descriptor.valid_columns = 0;69 _LocalGenerations[[slot]].parent_descriptor.data_type = TileDataType_FP64;70 _LocalGenerations[[slot]].parent_descriptor.layout = TileLayout_RowMajor;71 _LocalGenerations[[slot]].parent_descriptor.location = TileLocation_Any;72 _LocalGenerations[[slot]].parent_descriptor.cube_k_repeat = 0;73 _LocalGenerations[[slot]].parent_descriptor.cube_n_repeat = 0;74 _LocalGenerations[[slot]].parent_descriptor.cube_cell_count = 0;75 _LocalGenerations[[slot]].parent_descriptor.cube_storage_bytes = 0;76 _LocalGenerations[[slot]].covered_cells = Zeros{2048};77 _LocalGenerations[[slot]].ready_cells = Zeros{2048};78 _LocalGenerations[[slot]].writer_count = 0;79 _LocalGenerations[[slot]].consumer_count = 0;80 _LocalGenerations[[slot]].last_seen = FALSE;81 _LocalGenerations[[slot]].working_destination = 0;82 _LocalGenerations[[slot]].published_destination = 0;83 _LocalGenerations[[slot]].committed_destination = 0;84 _LocalGenerations[[slot]].committed_valid = FALSE;85end;86func AbortBundleLocalGeneration(hand: integer {0..3},87 participant_mask: bits(4))88begin89 let slot = BundleLocalGenerationSlot(hand, participant_mask);90 let committed_destination =91 _LocalGenerations[[slot]].committed_destination;92 let committed_valid = _LocalGenerations[[slot]].committed_valid;93 94 95 96 if _LocalGenerations[[slot]].open ||97 _LocalGenerations[[slot]].init_tpc_valid then98 let destination = _LocalGenerations[[slot]].working_destination;99 if _Tiles[[destination]].allocated &&100 (!committed_valid || destination != committed_destination) then101 ReleaseTile(destination);102 end;103 ClearBundleLocalGenerationState(slot);104 _LocalGenerations[[slot]].committed_destination =105 committed_destination;106 _LocalGenerations[[slot]].committed_valid = committed_valid;107 _LocalGenerations[[slot]].published_destination =108 committed_destination;109 _LocalGenerations[[slot]].published = committed_valid;110 _LocalGenerations[[slot]].closed = committed_valid;111 end;112end;113
114func AbortBundleLocalGenerationsForBundle()115begin116 for binding = 0 to PTO_BUNDLE_TILE_BINDING_COUNT - 1 do117 if _BundleTileBindings[[binding]].valid &&118 _BundleTileBindings[[binding]].destination_assemble.valid then119 let hand = UInt(_BundleTileBindings[[binding]].destination_hand)120 as integer {0..3};121 AbortBundleLocalGeneration(hand,122 _BundleTileBindings[[binding]].pe_mask);123 end;124 end;125end;126func SetBundleLocalGenerationFault(hand: integer {0..3},127 participant_mask: bits(4),128 fault: FaultCode)129begin130 let slot = BundleLocalGenerationSlot(hand, participant_mask);131 let restart_tpc = _LocalGenerations[[slot]].init_tpc;132 let restart_valid = _LocalGenerations[[slot]].init_tpc_valid;133 134 135 AbortBundleLocalGeneration(hand, participant_mask);136 SetFault(fault, ReadTPC());137 let ring = CurrentACR();138 if restart_valid && _TrapContexts[[ring]].valid then139 _TrapContexts[[ring]].tpc = restart_tpc;140 end;141end;142pure func BundleLocalGenerationCellCount(size_code: integer {1..12})143 => integer {1..2048}144begin145 return (TileSizeCodeBytes(size_code) DIVRM PTO_TILE_CELL_BYTES)146 as integer {1..2048};147end;148
149readonly func BundleLocalDestinationAllocationBytes(150 binding: BundleTileBindingIndex)151 => integer {0,128,256,512,1024,2048,4096,8192,16384,32768,65536,152 131072,262144}153begin154 let assemble = _BundleTileBindings[[binding]].destination_assemble;155 if assemble.valid && assemble.init then156 assert assemble.size_code >= 1 && assemble.size_code <= 12;157 return TileSizeCodeBytes(158 assemble.size_code as integer {1..12});159 end;160 return BundleTileDestinationSizeBytes(binding);161end;162
163pure func BundleLocalGenerationRangeOverlaps(164 left_offset: integer {0..2047}, left_count: integer {1..2048},165 right_offset: integer {0..2047}, right_count: integer {1..2048}) => boolean166begin167 return left_offset < right_offset + right_count &&168 right_offset < left_offset + left_count;169end;170
171readonly func BundleLocalGenerationCoverageComplete(172 slot: integer {0..63}, offset: Word, writer_size: integer {1..12},173 init: boolean, parent_size: integer {0..12}) => boolean174begin175 let raw_offset = UInt(offset);176 if raw_offset > 2047 then return FALSE; end;177 let offset_cells = raw_offset as integer {0..2047};178 let writer_cells = BundleLocalGenerationCellCount(writer_size);179 let required_cells = if init then180 BundleLocalGenerationCellCount(parent_size as integer {1..12})181 else _LocalGenerations[[slot]].parent_cell_count;182 var covered: bits(2048) = if init then Zeros{2048}183 else _LocalGenerations[[slot]].covered_cells;184 for cell = 0 to 2047 do185 if cell < writer_cells then covered[offset_cells + cell] = '1'; end;186 end;187 for required = 0 to 2047 do188 if required < required_cells && covered[required] == '0' then return FALSE; end;189 end;190 return TRUE;191end;192
193readonly func BundleLocalGenerationReadinessComplete(194 slot: integer {0..63}, offset: Word, writer_size: integer {1..12},195 init: boolean, parent_size: integer {0..12}) => boolean196begin197 let raw_offset = UInt(offset);198 if raw_offset > 2047 then return FALSE; end;199 let offset_cells = raw_offset as integer {0..2047};200 let writer_cells = BundleLocalGenerationCellCount(writer_size);201 let required_cells = if init then202 BundleLocalGenerationCellCount(parent_size as integer {1..12})203 else _LocalGenerations[[slot]].parent_cell_count;204 var ready: bits(2048) = if init then Zeros{2048}205 else _LocalGenerations[[slot]].ready_cells;206 for cell = 0 to 2047 do207 if cell < writer_cells then ready[offset_cells + cell] = '1'; end;208 end;209 for required = 0 to 2047 do210 if required < required_cells && ready[required] == '0' then return FALSE; end;211 end;212 return TRUE;213end;214
215readonly func BundleLocalGenerationDescriptorMatches(216 slot: integer {0..63}, destination: TileIndex,217 participant_mask: bits(4)) => boolean218begin219 let expected = _LocalGenerations[[slot]].parent_descriptor;220 let actual = _Tiles[[destination]];221 return expected.valid && actual.allocated &&222 expected.object_name == destination &&223 expected.object_kind == actual.storage_kind &&224 expected.participant_mask == participant_mask &&225 actual.capacity_bytes == expected.capacity_bytes &&226 actual.rows == expected.rows && actual.columns == expected.columns &&227 actual.valid_rows == expected.valid_rows &&228 actual.valid_columns == expected.valid_columns &&229 actual.data_type == expected.data_type &&230 actual.layout == expected.layout &&231 actual.location == expected.location &&232 actual.cube_k_repeat == expected.cube_k_repeat &&233 actual.cube_n_repeat == expected.cube_n_repeat &&234 actual.cube_cell_count == expected.cube_cell_count &&235 actual.cube_storage_bytes == expected.cube_storage_bytes &&236 _TileAllocationMasks[[destination]] == participant_mask;237end;238
239func ValidateBundleLocalGeneration() => boolean240begin241 242 243 244 for binding = 0 to PTO_BUNDLE_TILE_BINDING_COUNT - 1 do245 if _BundleTileBindings[[binding]].valid &&246 _BundleTileBindings[[binding]].destination_valid &&247 !_BundleTileBindings[[binding]].destination_assemble.valid then248 let hand = UInt(_BundleTileBindings[[binding]].destination_hand)249 as integer {0..3};250 if BundleLocalGenerationOpenForHand(hand) then251 SetFault(Fault_BundleControl, ReadTPC());252 return FALSE;253 end;254 end;255 end;256 for binding = 0 to PTO_BUNDLE_TILE_BINDING_COUNT - 1 do257 if _BundleTileBindings[[binding]].valid &&258 _BundleTileBindings[[binding]].destination_assemble.valid then259 let assemble = _BundleTileBindings[[binding]].destination_assemble;260 let hand = UInt(_BundleTileBindings[[binding]].destination_hand)261 as integer {0..3};262 let participant_mask = _BundleTileBindings[[binding]].pe_mask;263 let slot = BundleLocalGenerationSlot(hand, participant_mask);264 let writer_raw = _BundleTileBindings[[binding]].destination_size;265 if assemble.init && !_LocalGenerations[[slot]].open then266 267 268 _LocalGenerations[[slot]].init_tpc = ReadBPC();269 _LocalGenerations[[slot]].init_tpc_valid = TRUE;270 end;271 if !_BundleTileBindings[[binding]].destination_valid then272 SetBundleLocalGenerationFault(hand, participant_mask,273 Fault_BundleControl); return FALSE;274 end;275 if writer_raw < 1 || writer_raw > 12 then276 SetBundleLocalGenerationFault(hand, participant_mask,277 Fault_TileLegality); return FALSE;278 end;279 let writer_size = writer_raw as integer {1..12};280 if assemble.init && _LocalGenerations[[slot]].open then281 SetBundleLocalGenerationFault(hand, participant_mask,282 Fault_BundleControl); return FALSE;283 end;284 if !assemble.init && (!_LocalGenerations[[slot]].open ||285 _LocalGenerations[[slot]].closed) then286 if BundleLocalGenerationOpenForDifferentMask(287 hand, participant_mask) then288 SetFault(Fault_TileLegality, ReadTPC());289 return FALSE;290 end;291 SetBundleLocalGenerationFault(hand, participant_mask,292 Fault_BundleControl); return FALSE;293 end;294 let raw_offset = UInt(assemble.offset);295 if raw_offset > 2047 then296 SetBundleLocalGenerationFault(hand, participant_mask,297 Fault_TileLegality); return FALSE;298 end;299 let offset_cells = raw_offset as integer {0..2047};300 let writer_cells = BundleLocalGenerationCellCount(writer_size)301 as integer {1..2048};302 if assemble.init && (assemble.size_code < 1 ||303 assemble.size_code > 12) then304 SetBundleLocalGenerationFault(hand, participant_mask,305 Fault_TileLegality); return FALSE;306 end;307 let parent_cells = if assemble.init then308 BundleLocalGenerationCellCount(assemble.size_code as integer {1..12})309 else _LocalGenerations[[slot]].parent_cell_count;310 if offset_cells + writer_cells > parent_cells then311 SetBundleLocalGenerationFault(hand, participant_mask,312 Fault_TileLegality); return FALSE;313 end;314 let replay = BundleLocalGenerationReplay(315 slot, offset_cells, writer_cells, ReadBPC(),316 _BundleExecutionDomainToken);317 for prior = 0 to _LocalGenerations[[slot]].writer_count - 1318 looplimit 16 do319 if _LocalGenerations[[slot]].writers[[prior]].valid &&320 BundleLocalGenerationRangeOverlaps(offset_cells, writer_cells,321 _LocalGenerations[[slot]].writers[[prior]].offset_cells,322 _LocalGenerations[[slot]].writers[[prior]].cell_count323 as integer {1..2048}) && !replay then324 SetBundleLocalGenerationFault(hand, participant_mask,325 Fault_TileLegality); return FALSE;326 end;327 end;328 if assemble.last &&329 !BundleLocalGenerationCoverageComplete(330 slot, assemble.offset, writer_size, assemble.init,331 assemble.size_code) then332 SetBundleLocalGenerationFault(hand, participant_mask,333 Fault_TileLegality); return FALSE;334 end;335 end;336 end;337 return TRUE;338end;339
340func CommitBundleLocalGeneration()341begin342 for binding = 0 to PTO_BUNDLE_TILE_BINDING_COUNT - 1 do343 if _BundleTileBindings[[binding]].valid &&344 _BundleTileBindings[[binding]].destination_assemble.valid then345 let assemble = _BundleTileBindings[[binding]].destination_assemble;346 let hand = UInt(_BundleTileBindings[[binding]].destination_hand)347 as integer {0..3};348 let participant_mask = _BundleTileBindings[[binding]].pe_mask;349 let slot = BundleLocalGenerationSlot(hand, participant_mask);350 let writer_size = _BundleTileBindings[[binding]].destination_size351 as integer {1..12};352 let offset_cells = UInt(assemble.offset) as integer {0..2047};353 let writer_cells = BundleLocalGenerationCellCount(writer_size)354 as integer {1..2048};355 if assemble.init then356 let prior_committed_destination =357 _LocalGenerations[[slot]].committed_destination;358 let prior_committed_valid =359 _LocalGenerations[[slot]].committed_valid;360 _LocalGenerations[[slot]].open = TRUE;361 _LocalGenerations[[slot]].closed = FALSE;362 _LocalGenerations[[slot]].published = FALSE;363 _LocalGenerations[[slot]].destination_hand = hand;364 _LocalGenerations[[slot]].participant_mask = participant_mask;365 _LocalGenerations[[slot]].generation_instance = ReadBPC();366 _LocalGenerations[[slot]].init_tpc = ReadBPC();367 _LocalGenerations[[slot]].init_tpc_valid = TRUE;368 _LocalGenerations[[slot]].working_destination =369 _BundleTileBindings[[binding]].destination;370 _LocalGenerations[[slot]].committed_destination =371 prior_committed_destination;372 _LocalGenerations[[slot]].committed_valid =373 prior_committed_valid;374 _LocalGenerations[[slot]].published_destination =375 prior_committed_destination;376 let destination = _BundleTileBindings[[binding]].destination;377 _LocalGenerations[[slot]].parent_descriptor.valid = TRUE;378 _LocalGenerations[[slot]].parent_descriptor.object_name = destination;379 _LocalGenerations[[slot]].parent_descriptor.object_kind =380 _Tiles[[destination]].storage_kind;381 _LocalGenerations[[slot]].parent_descriptor.participant_mask = participant_mask;382 _LocalGenerations[[slot]].parent_descriptor.capacity_bytes = _Tiles[[destination]].capacity_bytes;383 _LocalGenerations[[slot]].parent_descriptor.rows = _Tiles[[destination]].rows;384 _LocalGenerations[[slot]].parent_descriptor.columns = _Tiles[[destination]].columns;385 _LocalGenerations[[slot]].parent_descriptor.valid_rows = _Tiles[[destination]].valid_rows;386 _LocalGenerations[[slot]].parent_descriptor.valid_columns = _Tiles[[destination]].valid_columns;387 _LocalGenerations[[slot]].parent_descriptor.data_type = _Tiles[[destination]].data_type;388 _LocalGenerations[[slot]].parent_descriptor.layout = _Tiles[[destination]].layout;389 _LocalGenerations[[slot]].parent_descriptor.location = _Tiles[[destination]].location;390 _LocalGenerations[[slot]].parent_descriptor.cube_k_repeat = _Tiles[[destination]].cube_k_repeat;391 _LocalGenerations[[slot]].parent_descriptor.cube_n_repeat = _Tiles[[destination]].cube_n_repeat;392 _LocalGenerations[[slot]].parent_descriptor.cube_cell_count = _Tiles[[destination]].cube_cell_count;393 _LocalGenerations[[slot]].parent_descriptor.cube_storage_bytes = _Tiles[[destination]].cube_storage_bytes;394 _LocalGenerations[[slot]].parent_size_code = assemble.size_code;395 _LocalGenerations[[slot]].parent_cell_count = BundleLocalGenerationCellCount(assemble.size_code as integer {1..12});396 _LocalGenerations[[slot]].covered_cells = Zeros{2048};397 _LocalGenerations[[slot]].ready_cells = Zeros{2048};398 _LocalGenerations[[slot]].writer_count = 0;399 _LocalGenerations[[slot]].consumer_count = 0;400 end;401 var covered_cells: bits(2048) =402 _LocalGenerations[[slot]].covered_cells;403 var ready_cells: bits(2048) = _LocalGenerations[[slot]].ready_cells;404 let replay = BundleLocalGenerationReplay(405 slot, offset_cells, writer_cells, ReadBPC(),406 _BundleExecutionDomainToken);407 if !replay then408 409 410 411 assert _LocalGenerations[[slot]].writer_count < 16;412 let ordinal = _LocalGenerations[[slot]].writer_count;413 _LocalGenerations[[slot]].writers[[ordinal]].valid = TRUE;414 _LocalGenerations[[slot]].writers[[ordinal]].offset_cells = offset_cells;415 _LocalGenerations[[slot]].writers[[ordinal]].cell_count = writer_cells;416 _LocalGenerations[[slot]].writers[[ordinal]].destination = _BundleTileBindings[[binding]].destination;417 418 419 420 _LocalGenerations[[slot]].writers[[ordinal]].ready = FALSE;421 _LocalGenerations[[slot]].writers[[ordinal]].identity422 .instruction_instance = ReadBPC();423 _LocalGenerations[[slot]].writers[[ordinal]].identity424 .execution_domain_token = _BundleExecutionDomainToken;425 _LocalGenerations[[slot]].writer_count = (ordinal + 1) as integer {0..16};426 for cell = 0 to 2047 do427 if cell < writer_cells then428 let covered_index = (offset_cells + cell)429 as integer {0..2047};430 covered_cells[covered_index] = '1';431 end;432 end;433 end;434 _LocalGenerations[[slot]].covered_cells = covered_cells;435 _LocalGenerations[[slot]].ready_cells = ready_cells;436 if assemble.last then437 _LocalGenerations[[slot]].last_seen = TRUE;438 _LocalGenerations[[slot]].closed = TRUE;439 if BundleLocalGenerationPublicationEligible(slot) then440 _LocalGenerations[[slot]].open = FALSE;441 _LocalGenerations[[slot]].published = TRUE;442 _LocalGenerations[[slot]].published_destination =443 _BundleTileBindings[[binding]].destination;444 _LocalGenerations[[slot]].committed_destination =445 _BundleTileBindings[[binding]].destination;446 _LocalGenerations[[slot]].committed_valid = TRUE;447 else448 449 450 451 _LocalGenerations[[slot]].open = FALSE;452 _LocalGenerations[[slot]].published = FALSE;453 end;454 end;455 end;456 end;457end;458
459func ReuseBundleLocalGenerationDestination() => boolean460begin461 for binding = 0 to PTO_BUNDLE_TILE_BINDING_COUNT - 1 do462 if _BundleTileBindings[[binding]].valid &&463 _BundleTileBindings[[binding]].destination_assemble.valid then464 let assemble = _BundleTileBindings[[binding]].destination_assemble;465 let hand = UInt(_BundleTileBindings[[binding]].destination_hand)466 as integer {0..3};467 let participant_mask = _BundleTileBindings[[binding]].pe_mask;468 let slot = BundleLocalGenerationSlot(hand, participant_mask);469 if !assemble.init then470 if !_LocalGenerations[[slot]].open then471 SetBundleLocalGenerationFault(hand, participant_mask,472 Fault_BundleControl); return FALSE;473 end;474 let destination = _LocalGenerations[[slot]].working_destination;475 if !_Tiles[[destination]].allocated ||476 !BundleLocalGenerationDescriptorMatches(477 slot, destination, participant_mask) then478 SetBundleLocalGenerationFault(hand, participant_mask,479 Fault_TileLegality); return FALSE;480 end;481 _BundleTileBindings[[binding]].destination = destination;482 _BundleTileBindings[[binding]].destination_allocated_by_bundle = TRUE;483 _BundleTileBindings[[binding]].destination_reused_by_generation = TRUE;484 end;485 end;486 end;487 return TRUE;488end;489