12
345678910pure func SharedTileArrayIndex(shared_tile_id: SharedTileID) => SharedTileIndex11begin12 return UInt(shared_tile_id) as SharedTileIndex;13end;14
15readonly func SharedTileRecord(shared_tile_id: SharedTileID) => SharedTileInfo16begin17 return _SharedTiles[[SharedTileArrayIndex(shared_tile_id)]];18end;19
20readonly func SharedTileFullyInitialized(shared_tile_id: SharedTileID) => boolean21begin22 let shared = SharedTileRecord(shared_tile_id);23 return shared.descriptor_valid &&24 shared.initialized_mask == shared.allocation_mask &&25 shared.tile.contents_defined;26end;27
28readonly func SharedTilePublished(shared_tile_id: SharedTileID) => boolean29begin30 let shared = SharedTileRecord(shared_tile_id);31 return SharedTileFullyInitialized(shared_tile_id) &&32 shared.whole_parent_ready && shared.published;33end;34
35readonly func SharedTileCooperativeMatrixReady(36 shared_tile_id: SharedTileID) => boolean37begin38 let shared = SharedTileRecord(shared_tile_id);39 return SharedTileDescriptorLegal(shared_tile_id) &&40 shared.whole_parent_ready && shared.published &&41 shared.tile.contents_defined;42end;43
44readonly func SharedTileDescriptorLegal(shared_tile_id: SharedTileID) => boolean45begin46 let shared = SharedTileRecord(shared_tile_id);47 return shared.descriptor_valid && shared.tile.allocated &&48 shared.allocation_mask != Zeros{4} &&49 (shared.initialized_mask AND NOT shared.allocation_mask) == Zeros{4} &&50 SharedTileCapacityIsLegal(shared.tile.capacity_bytes) &&51 TileShapeMatchesCapacity(shared.tile.capacity_bytes,52 shared.tile.rows, shared.tile.columns,53 shared.tile.data_type) &&54 shared.tile.valid_rows <= shared.tile.rows &&55 shared.tile.valid_columns <= shared.tile.columns &&56 shared.tile.rows * shared.tile.columns <=57 TileLogicalElementCapacity(shared.tile.capacity_bytes,58 shared.tile.data_type) &&59 TileGenericIndexingPermitted(shared.tile);60end;61
62readonly func SharedTileDescriptorsCompatible(left: TileInfo,63 right: TileInfo) => boolean64begin65 return left.allocated && right.allocated &&66 !TileLayoutIsCube(left.layout) &&67 !TileLayoutIsCube(right.layout) &&68 left.capacity_bytes == right.capacity_bytes &&69 left.rows == right.rows && left.columns == right.columns &&70 left.valid_rows == right.valid_rows &&71 left.valid_columns == right.valid_columns &&72 left.data_type == right.data_type &&73 left.layout == right.layout && left.location == right.location &&74 left.cube_k_repeat == right.cube_k_repeat &&75 left.cube_n_repeat == right.cube_n_repeat &&76 left.cube_cell_count == right.cube_cell_count &&77 left.cube_storage_bytes == right.cube_storage_bytes;78end;79
80readonly func SharedTileUpdateCompatible(shared_tile_id: SharedTileID, tile: TileInfo,81 pe_mask: bits(4)) => boolean82begin83 if pe_mask == Zeros{4} then return TRUE; end;84 if TileLayoutIsCube(tile.layout) ||85 !SharedTileCapacityIsLegal(tile.capacity_bytes) ||86 !TileShapeMatchesCapacity(tile.capacity_bytes, tile.rows,87 tile.columns, tile.data_type) ||88 tile.valid_rows > tile.rows ||89 tile.valid_columns > tile.columns ||90 tile.rows * tile.columns >91 TileLogicalElementCapacity(tile.capacity_bytes, tile.data_type) then92 return FALSE;93 end;94 let old = SharedTileRecord(shared_tile_id);95 if old.descriptor_valid then96 return (pe_mask AND NOT old.allocation_mask) == Zeros{4} &&97 SharedTileDescriptorsCompatible(old.tile, tile);98 end;99 return SharedTileCapacityInUse() + tile.capacity_bytes <=100 SharedTileCapacityLimitBytes();101end;102
103104105106readonly func UndefinedSharedTileWord(shared_tile_id: SharedTileID,107 element: PackedTileElementIndex) => Word108begin109 return ZeroExtend{PTO_XLEN}(shared_tile_id) XOR110 (Zeros{PTO_XLEN} + element);111end;112
113readonly func ReadSharedTileWord(shared_tile_id: SharedTileID,114 element: PackedTileElementIndex) => Word115begin116 let shared = SharedTileRecord(shared_tile_id);117 if !shared.descriptor_valid || !shared.whole_parent_ready ||118 !TileLogicalElementDefined(shared.tile, element) then119 return UndefinedSharedTileWord(shared_tile_id, element);120 end;121 return TileReadLogicalElement(shared.tile, element);122end;123
124125126127readonly func MaterializeSharedTile(shared_tile_id: SharedTileID,128 pe_mask: bits(4)) => TileInfo129begin130 let shared = SharedTileRecord(shared_tile_id);131 assert SharedTilePublished(shared_tile_id);132 var tile = shared.tile;133 assert tile.contents_defined;134 tile.location = TileLocation_Any;135 return tile;136end;137
138readonly func SharedTileReadSchemaLegalAtCapacity(139 shared_tile_id: SharedTileID, valid_rows: integer {0..65535},140 valid_columns: integer {0..65535}, columns: integer {0..65535},141 data_type: TileDataType, layout: TileLayout,142 capacity_bytes: integer {0..262144}) => boolean143begin144 if TileLayoutIsCube(layout) then return FALSE; end;145 let shared = SharedTileRecord(shared_tile_id);146 if shared.descriptor_valid then147 return SharedTileDescriptorLegal(shared_tile_id) &&148 shared.tile.capacity_bytes == capacity_bytes &&149 shared.tile.columns == columns &&150 valid_rows <= shared.tile.valid_rows &&151 valid_columns <= shared.tile.valid_columns &&152 shared.tile.data_type == data_type &&153 shared.tile.layout == layout;154 end;155 return SharedTileCapacityIsLegal(capacity_bytes) &&156 TileDescriptorShapeLegal(capacity_bytes, columns, valid_rows,157 valid_columns, data_type) &&158 DerivedTileRows(capacity_bytes, columns, data_type) * columns <=159 TileLogicalElementCapacity(capacity_bytes, data_type);160end;161
162readonly func SharedTileReadSchemaLegal(163 shared_tile_id: SharedTileID, valid_rows: integer {0..65535},164 valid_columns: integer {0..65535}, columns: integer {0..65535},165 data_type: TileDataType, layout: TileLayout) => boolean166begin167 let shared = SharedTileRecord(shared_tile_id);168 let capacity_bytes = if shared.descriptor_valid then169 shared.tile.capacity_bytes170 else171 MinimumTileCapacityBytesForShape(columns, valid_rows,172 valid_columns, data_type);173 return capacity_bytes != 0 && SharedTileReadSchemaLegalAtCapacity(174 shared_tile_id, valid_rows, valid_columns, columns, data_type, layout,175 capacity_bytes);176end;177
178readonly func MaterializeSharedTileReadValues(179 shared_tile_id: SharedTileID, tile: TileInfo) => TileInfo180begin181 var result = tile;182 for row = 0 to result.valid_rows - 1 looplimit 65536 do183 for column = 0 to result.valid_columns - 1 looplimit 65536 do184 let element = TileLogicalLinearIndex(185 result, row as integer {0..65535},186 column as integer {0..65535});187 result = TileInfoWithLogicalElement(result, element,188 ReadSharedTileWord(shared_tile_id, element));189 end;190 end;191 return result;192end;193
194195196197198readonly func MaterializeSharedTileForReadSchema(199 shared_tile_id: SharedTileID, valid_rows: integer {0..65535},200 valid_columns: integer {0..65535}, columns: integer {0..65535},201 data_type: TileDataType, layout: TileLayout) => TileInfo202begin203 assert SharedTileReadSchemaLegal(shared_tile_id, valid_rows, valid_columns,204 columns, data_type, layout);205 let shared = SharedTileRecord(shared_tile_id);206 let capacity_bytes = if shared.descriptor_valid then207 shared.tile.capacity_bytes208 else209 MinimumTileCapacityBytesForShape(columns, valid_rows,210 valid_columns, data_type);211 var tile = shared.tile;212 tile.allocated = TRUE;213 tile.contents_defined = FALSE;214 tile.defined_elements = Zeros{PTO_MODEL_TILE_ELEMENTS};215 tile.defined_valid_elements = 0;216 tile.packed_defined_elements = ZeroPackedTileDefinedElements();217 tile.capacity_bytes = capacity_bytes;218 tile.rows = DerivedTileRows(capacity_bytes, columns, data_type);219 tile.columns = columns;220 tile.valid_rows = valid_rows;221 tile.valid_columns = valid_columns;222 tile.data_type = data_type;223 tile.layout = layout;224 tile.location = TileLocation_Any;225 tile.cube_k_repeat = 0;226 tile.cube_n_repeat = 0;227 tile.cube_cell_count = 0;228 tile.cube_storage_bytes = 0;229 return MaterializeSharedTileReadValues(shared_tile_id, tile);230end;231
232readonly func MaterializeSharedTileForReadSchemaAtCapacity(233 shared_tile_id: SharedTileID, valid_rows: integer {0..65535},234 valid_columns: integer {0..65535}, columns: integer {0..65535},235 data_type: TileDataType, layout: TileLayout,236 capacity_bytes: integer {0..262144}) => TileInfo237begin238 assert SharedTileReadSchemaLegalAtCapacity(shared_tile_id, valid_rows,239 valid_columns, columns, data_type, layout, capacity_bytes);240 var tile = SharedTileRecord(shared_tile_id).tile;241 tile.allocated = TRUE;242 tile.contents_defined = FALSE;243 tile.defined_elements = Zeros{PTO_MODEL_TILE_ELEMENTS};244 tile.defined_valid_elements = 0;245 tile.packed_defined_elements = ZeroPackedTileDefinedElements();246 tile.capacity_bytes = capacity_bytes;247 tile.rows = DerivedTileRows(capacity_bytes, columns, data_type);248 tile.columns = columns;249 tile.valid_rows = valid_rows;250 tile.valid_columns = valid_columns;251 tile.data_type = data_type;252 tile.layout = layout;253 tile.location = TileLocation_Any;254 tile.cube_k_repeat = 0;255 tile.cube_n_repeat = 0;256 tile.cube_cell_count = 0;257 tile.cube_storage_bytes = 0;258 return MaterializeSharedTileReadValues(shared_tile_id, tile);259end;260
261readonly func SharedTileProspectiveFullyInitialized(262 shared_tile_id: SharedTileID, tile: TileInfo, pe_mask: bits(4)) => boolean263begin264 if pe_mask == Zeros{4} ||265 !SharedTileUpdateCompatible(shared_tile_id, tile, pe_mask) then266 return FALSE;267 end;268 let old = SharedTileRecord(shared_tile_id);269 if !old.descriptor_valid then return TRUE; end;270 return (old.initialized_mask OR pe_mask) == old.allocation_mask;271end;272
273274275276277func AtomicUpdateSharedTileWithPublication(278 shared_tile_id: SharedTileID, tile: TileInfo, pe_mask: bits(4),279 publish: boolean) => boolean280begin281 if pe_mask == Zeros{4} then return TRUE; end;282 assert tile.allocated;283 let index = SharedTileArrayIndex(shared_tile_id);284 let old = _SharedTiles[[index]];285 if !SharedTileUpdateCompatible(shared_tile_id, tile, pe_mask) then286 return FALSE;287 end;288 var updated = old;289 if !old.descriptor_valid then290 let direct_complete = PEMaskPopulation(pe_mask) == 1 ||291 pe_mask == '1111';292 updated.descriptor_valid = TRUE;293 updated.allocation_mask = pe_mask;294 updated.tile = tile;295 updated.initialized_mask = pe_mask;296 updated.whole_parent_ready = publish && direct_complete &&297 tile.contents_defined;298 updated.published = updated.whole_parent_ready;299 elsif publish && PEMaskPopulation(pe_mask) == 1 then300 updated.allocation_mask = pe_mask;301 updated.initialized_mask = pe_mask;302 updated.tile = tile;303 updated.tile.contents_defined = TRUE;304 updated.tile.defined_valid_elements =305 (updated.tile.valid_rows * updated.tile.valid_columns)306 as integer {0..524288};307 updated.whole_parent_ready = TRUE;308 updated.published = TRUE;309 else310 for element = 0 to tile.rows * tile.columns - 1311 looplimit 524288 do312 let region = SharedTileElementRegion(tile,313 element as PackedTileElementIndex);314 if pe_mask[PTOPEMaskBitOfPEIdentity(region)] == '1' then315 if TileLogicalElementDefined(tile,316 element as PackedTileElementIndex) then317 updated.tile = TileInfoWithLogicalElement(updated.tile,318 element as PackedTileElementIndex,319 TileReadLogicalElement(tile,320 element as PackedTileElementIndex));321 end;322 end;323 end;324 updated.initialized_mask = old.initialized_mask OR pe_mask;325 326 327 328 updated.tile.contents_defined =329 updated.initialized_mask == updated.allocation_mask;330 if updated.tile.contents_defined then331 updated.tile.defined_valid_elements =332 (updated.tile.valid_rows * updated.tile.valid_columns)333 as integer {0..524288};334 end;335 let direct_complete = pe_mask == '1111';336 updated.whole_parent_ready = old.whole_parent_ready ||337 (publish && direct_complete && updated.tile.contents_defined);338 updated.published = old.published ||339 (publish && direct_complete && updated.tile.contents_defined);340 end;341 _SharedTiles[[index]] = updated;342 return TRUE;343end;344
345func AtomicUpdateSharedTile(shared_tile_id: SharedTileID, tile: TileInfo,346 pe_mask: bits(4)) => boolean347begin348 return AtomicUpdateSharedTileWithPublication(349 shared_tile_id, tile, pe_mask, TRUE);350end;351
352func InstallSharedTile(shared_tile_id: SharedTileID, tile: TileInfo, pe_mask: bits(4))353begin354 let updated = AtomicUpdateSharedTile(shared_tile_id, tile, pe_mask);355 assert updated;356end;357