Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions include/common/layout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ enum class LayoutEnum {
kColMajor = 2,
};

// Backfilled from PTO v0.58 (layout.hpp) so the datatype-reinterpret view can
// forward SourceTile::Compact. This baseline has no compact tiles: Tile
// defaults to CompactMode::Null (see pto_tile.hpp).
enum class CompactMode {
Null,
Normal,
RowPlusOne,
};

enum LayoutCvtEnum : uint64_t {
NORM = 0,
ND2DN, ND2ZZ, ND2ZN, ND2NZ, ND2NN,
Expand Down
205 changes: 198 additions & 7 deletions include/common/pto_tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,38 @@ namespace pto {
/// // signed less than comparison
/// }
/// @endcode
enum class CmpMode {
EQ, ///< Equal (==)
NE, ///< Not equal (!=)
GT, ///< Greater than (>)
LT, ///< Less than (<)
GE, ///< Greater than or equal (>=)
LE, ///< Less than or equal (<=)
// PTO 0.58 B.DATR CMode[31:29] encoding. Values are explicit and MUST match
// the ISA: EQ=0 NE=1 LT=2 GT=3 LE=4 GE=5 (do not rely on declaration order).
enum class CmpMode : uint8_t {
EQ = 0, ///< Equal (==)
NE = 1, ///< Not equal (!=)
LT = 2, ///< Less than (<)
GT = 3, ///< Greater than (>)
LE = 4, ///< Less than or equal (<=)
GE = 5, ///< Greater than or equal (>=)
};

/// Compile-time validity check for the six ISA comparison modes. Rejects any
/// out-of-range value that a bogus static_cast would otherwise smuggle into
/// the B.DATR CMode field.
constexpr bool is_valid_cmp_mode(CmpMode Mode) {
switch (Mode) {
case CmpMode::EQ:
case CmpMode::NE:
case CmpMode::LT:
case CmpMode::GT:
case CmpMode::LE:
case CmpMode::GE:
return true;
}
return false;
}

/// CmpMode -> B.DATR CMode[31:29] immediate (the enum value itself).
constexpr unsigned cmp_mode_code(CmpMode Mode) {
return static_cast<unsigned>(Mode);
}

/// Padding Value : keep SAME with asm encoding
enum class PadValue {
Zero = 0,
Expand Down Expand Up @@ -606,6 +629,25 @@ struct Tile {
static constexpr int SFractalSize = SFractalSize_;
static constexpr PadValue PadVal = PadVal_;

// Backfilled from PTO v0.58 so reinterpret_tile's view can forward these.
// LogicalTileBytes matches this baseline's existing kBytes formula; there are
// no compact tiles here so Compact is fixed at Null. Downstream ops read
// tile_type_traits<TileDType>::IsValidActiveSize, not these members, so the
// backfill is inert outside the reinterpret view.
static constexpr CompactMode Compact = CompactMode::Null;
static constexpr int LogicalTileBytes =
(Rows * Cols * type_traits<DType>::bits + 7) / 8;
static constexpr int TilesizeCode =
LogicalTileBytes == 128 ? __tilesize_128B :
LogicalTileBytes == 256 ? __tilesize_256B :
LogicalTileBytes == 512 ? __tilesize_512B :
LogicalTileBytes == 1024 ? __tilesize_1KB :
LogicalTileBytes == 2048 ? __tilesize_2KB :
LogicalTileBytes == 4096 ? __tilesize_4KB :
LogicalTileBytes == 8192 ? __tilesize_8KB : __tilesize_unknown;
static constexpr bool IsValidActiveSize =
TilesizeCode >= __tilesize_128B && TilesizeCode <= __tilesize_8KB;

// constructor for static shape
Tile() { };
template <int RowMask = ValidRow, int ColMask = ValidCol>
Expand Down Expand Up @@ -1242,4 +1284,153 @@ void print_tile_info() {

} // namespace pto

//===--- Tile datatype reinterpret view (PTO v0.58) ---===//
// reinterpret_tile<NewDType>(src): zero-instruction datatype reinterpret.
// The underlying Tile register/storage bit pattern is unchanged; only the
// static DType (and downstream ISA datatype encoding) is re-interpreted by
// the view. First phase: Local Tile -> Local view, equal-bit-width only,
// layout/shape/valid/Location preserved, no TCVT, no payload copy.
namespace pto {

// Whether T has a PTO TypeCode (has a type_traits specialization).
template <typename T, typename = void> struct has_ptotype_traits : std::false_type {};
template <typename T>
struct has_ptotype_traits<T, std::void_t<decltype(type_traits<T>::TypeCode)>>
: std::true_type {};

template <typename T>
inline constexpr bool is_supported_dtype_v =
has_ptotype_traits<std::remove_cv_t<T>>::value &&
(type_traits<std::remove_cv_t<T>>::bits > 0);

// Zero-instruction datatype view over an existing Local Tile. Storage carrier
// (TileDType) and data() forward to the source; DType and all shape/role
// statics are re-declared so downstream ops see NewDType while binding the
// source's exact Tile register.
template <typename NewDType, typename SourceTile>
class ReinterpretedTileView {
public:
using DType = NewDType;
using Source = SourceTile;
// Same storage carrier as the source Tile: on __linx this is the fixed
// 4 KB TileDType, so tile_type_traits<...TileDType>::TilesizeCode and the
// physical bytes are unchanged by the reinterpret.
using TileDType = typename SourceTile::TileDType;

static constexpr Location Loc = SourceTile::Loc;
static constexpr int Rows = SourceTile::Rows;
static constexpr int Cols = SourceTile::Cols;
static constexpr int RowStride = SourceTile::RowStride;
static constexpr int ColStride = SourceTile::ColStride;
static constexpr int ValidRow = SourceTile::ValidRow;
static constexpr int ValidCol = SourceTile::ValidCol;
static constexpr BLayout BFractal = SourceTile::BFractal;
static constexpr SLayout SFractal = SourceTile::SFractal;
static constexpr int SFractalSize = SourceTile::SFractalSize;
static constexpr PadValue PadVal = SourceTile::PadVal;
static constexpr CompactMode Compact = SourceTile::Compact;
static constexpr bool isRowMajor = SourceTile::isRowMajor;
static constexpr bool isBoxedLayout = SourceTile::isBoxedLayout;
static constexpr bool isInnerRowMajor = SourceTile::isInnerRowMajor;
static constexpr bool isInnerColMajor = SourceTile::isInnerColMajor;
static constexpr int InnerRows = SourceTile::InnerRows;
static constexpr int InnerCols = SourceTile::InnerCols;
static constexpr int InnerNumel = SourceTile::InnerNumel;
static constexpr int Numel = SourceTile::Numel;
static constexpr int byteSize = SourceTile::byteSize;
// Physical storage identity: the view occupies exactly the source bytes.
static constexpr int kBytes = SourceTile::kBytes;
static constexpr int LogicalTileBytes = SourceTile::LogicalTileBytes;
static constexpr int TilesizeCode = SourceTile::TilesizeCode;
static constexpr bool IsValidActiveSize = SourceTile::IsValidActiveSize;

explicit constexpr ReinterpretedTileView(SourceTile &Source)
: SourceValue(Source) {}

// Same register carrier as the source (no copy). Only const access is
// exposed for const sources; the non-const path keeps the same carrier.
decltype(auto) data() { return SourceValue.data(); }
decltype(auto) data() const { return SourceValue.data(); }

template <int RowMask = ValidRow>
static constexpr std::enable_if_t<(RowMask > 0), int> GetValidRow() {
return SourceTile::template GetValidRow<RowMask>();
}
template <int RowMask = ValidRow>
std::enable_if_t<RowMask == -1, int> GetValidRow() const {
return SourceValue.GetValidRow();
}
template <int ColMask = ValidCol>
static constexpr std::enable_if_t<(ColMask > 0), int> GetValidCol() {
return SourceTile::template GetValidCol<ColMask>();
}
template <int ColMask = ValidCol>
std::enable_if_t<ColMask == -1, int> GetValidCol() const {
return SourceValue.GetValidCol();
}

private:
SourceTile &SourceValue;
};

// A ReinterpretedTileView is a Local tile-shaped operand (not Shared).
template <typename NewDType, typename SourceTile>
struct is_tile<ReinterpretedTileView<NewDType, SourceTile>> : std::true_type {
static constexpr SLayout layout_enum = SourceTile::SFractal;
};

// Equal bit-width is required: the reinterpret must not change the number of
// logical elements, physical bytes or TileSizeCode.
template <typename SourceTile, typename NewDType>
constexpr bool reinterpret_tile_equal_width_v =
type_traits<typename SourceTile::DType>::bits ==
type_traits<NewDType>::bits;

// The source must be an ordinary Local Tile (Shared is out of scope for the
// first phase; a Shared view would need the Sr binder contract).
template <typename SourceTile>
constexpr bool reinterpret_tile_source_is_local_v =
is_tile<SourceTile>::value &&
SourceTile::Loc != Location::Shared;

// The new dtype must be encodable in the source's layout. We accept any
// equal-width dtype whose type_traits exists; boxed/fractal layouts are
// preserved unchanged because rows/cols/inner box are untouched, so the
// existing Tile layout static_asserts remain valid for the same dimensions.
// A NewDType with no PTO TypeCode is rejected by is_supported_dtype_v.
template <typename SourceTile, typename NewDType>
constexpr bool reinterpret_tile_layout_legal_v =
reinterpret_tile_equal_width_v<SourceTile, NewDType> &&
is_supported_dtype_v<NewDType>;

// Physical storage preservation: same bytes, same TilesizeCode, same carrier.
template <typename SourceTile, typename NewDType>
constexpr bool reinterpret_tile_storage_compatible_v =
reinterpret_tile_equal_width_v<SourceTile, NewDType>;

// The view must not dangle: it holds a reference, so it must not be bound to
// a temporary Tile. reinterpret_tile takes SourceTile& (non-const), which
// already rejects rvalues; the const overload takes const SourceTile&, which
// also rejects prvalue temporaries (they bind to const& only via materialized
// temporaries -- rejected by requiring a named lvalue at the call site).

/// Zero-instruction datatype reinterpret over a Local Tile.
template <typename NewDType, is_tile_data_v SourceTile>
inline auto reinterpret_tile(SourceTile &Source) {
using OldDType = typename SourceTile::DType;
static_assert(is_supported_dtype_v<NewDType>,
"reinterpret_tile target dtype has no PTO TypeCode");
static_assert(reinterpret_tile_source_is_local_v<SourceTile>,
"reinterpret_tile first phase supports Local Tiles only"
" (Shared requires a separate Shared view)");
static_assert(reinterpret_tile_layout_legal_v<SourceTile, NewDType>,
"reinterpret_tile requires equal-bit-width dtypes "
"compatible with the source layout");
static_assert(reinterpret_tile_storage_compatible_v<SourceTile, NewDType>,
"reinterpret_tile must preserve the source Tile storage");
return ReinterpretedTileView<NewDType, SourceTile>(Source);
}

} // namespace pto

#endif
10 changes: 10 additions & 0 deletions include/cpu_sim/TCmp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ void TCmp_Vec_RowMajor(typename tile_shape_out::TileDType dst,
dst[idx] = static_cast<typename tile_shape_out::DType>( src0[idx] >= src1[idx]);
} else if constexpr (mode == CmpMode::LE) {
dst[idx] = static_cast<typename tile_shape_out::DType>( src0[idx] <= src1[idx]);
} else {
static_assert(mode == CmpMode::EQ || mode == CmpMode::NE ||
mode == CmpMode::LT || mode == CmpMode::GT ||
mode == CmpMode::LE || mode == CmpMode::GE,
"TCMP mode must be one of the six ISA comparison modes");
}
}
}
Expand All @@ -48,6 +53,11 @@ void TCmp_Vec_ColMajor(
dst[idx] = static_cast<typename tile_shape_out::DType>( src0[idx] >= src1[idx]);
} else if constexpr (mode == CmpMode::LE) {
dst[idx] = static_cast<typename tile_shape_out::DType>( src0[idx] <= src1[idx]);
} else {
static_assert(mode == CmpMode::EQ || mode == CmpMode::NE ||
mode == CmpMode::LT || mode == CmpMode::GT ||
mode == CmpMode::LE || mode == CmpMode::GE,
"TCMP mode must be one of the six ISA comparison modes");
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions include/jcore/TCmp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ void __vec__ TCmp_Vec_RowMajor(typename tile_shape_out::TileDType __out__ dst,
result = static_cast<typename tile_shape_out::DType>( a >= b);
} else if constexpr (mode == CmpMode::LE) {
result = static_cast<typename tile_shape_out::DType>( a <= b);
} else {
static_assert(mode == CmpMode::EQ || mode == CmpMode::NE ||
mode == CmpMode::LT || mode == CmpMode::GT ||
mode == CmpMode::LE || mode == CmpMode::GE,
"TCMP mode must be one of the six ISA comparison modes");
}
blkv_get_tile_ptr(dst)[index] = result;
}
Expand Down Expand Up @@ -57,6 +62,11 @@ void __vec__ TCmp_Vec_ColMajor(typename tile_shape_out::TileDType __out__ dst,
result = static_cast<typename tile_shape_out::DType>( a >= b);
} else if constexpr (mode == CmpMode::LE) {
result = static_cast<typename tile_shape_out::DType>( a <= b);
} else {
static_assert(mode == CmpMode::EQ || mode == CmpMode::NE ||
mode == CmpMode::LT || mode == CmpMode::GT ||
mode == CmpMode::LE || mode == CmpMode::GE,
"TCMP mode must be one of the six ISA comparison modes");
}
blkv_get_tile_ptr(dst)[index] = result;
}
Expand Down
Loading