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
2 changes: 1 addition & 1 deletion examples/Makefile.peano
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ CXX = clang++ --target=aie2-none-unknown-elf
CXXFLAGS = -std=c++2b -Wno-unknown-attributes
CPPFLAGS = -I../include -I$(XILINX_VITIS_AIETOOLS)/include

SOURCES := add.cpp aligned_memcpy.cpp gemm_bf16xbf16.cpp gemm_int8xint8_sparse.cpp \
SOURCES := add.cpp aligned_memcpy.cpp cascade.cpp gemm_bf16xbf16.cpp gemm_int8xint8_sparse.cpp \
lazy.cpp lookup_table.cpp mmul.cpp operators.cpp
TARGETS := $(SOURCES:.cpp=.o)

Expand Down
33 changes: 33 additions & 0 deletions examples/cascade.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT
// Copyright (C) 2022 Xilinx, Inc.
// Copyright (C) 2022-2026 Advanced Micro Devices, Inc.

#include <aie_api/aie.hpp>

// The adf-free cascade accessors are available where __AIE_API_HAS_CASCADE__ is
// set (today: aie2p under Peano; see aie_api/cascade.hpp). Guarding the example
// on the capability macro keeps a default build green on architectures and
// compilers that do not implement it yet, and exercises the accessors where it
// is available, e.g. clang++ --target=aie2p-none-unknown-elf -I../include -c cascade.cpp.
#if __AIE_API_HAS_CASCADE__

//![Adf-free cascade round-trip]
// Put a 16-lane int32 vector to the master cascade, then read one back from the
// slave cascade. On real hardware the two ends are on adjacent cores; a fused
// cross-core reduction issues the put on one core and the get on the next.
extern "C" aie::vector<int32_t, 16> cascade_passthrough_i32(aie::vector<int32_t, 16> x)
{
aie::cascade_out(x);
return aie::cascade_in_i32();
}

// The accumulator path, which a fused cross-core K-reduction uses (partial sums
// travel as accumulators).
extern "C" aie::accum<acc32, 16> cascade_passthrough_acc32(aie::accum<acc32, 16> a)
{
aie::cascade_out(a);
return aie::cascade_in_acc32();
}
//![Adf-free cascade round-trip]

#endif // __AIE_API_HAS_CASCADE__
8 changes: 7 additions & 1 deletion include/aie_api/aie.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
#if AIE_API_ML_VERSION >= 210
#include "block_vector.hpp"
#endif
#include "cascade.hpp"
#include "concepts.hpp"
#include "expr.hpp"
#include "fft.hpp"
Expand Down Expand Up @@ -8247,7 +8248,12 @@ BINARY_OP_IMPL(Neg)

}

#ifdef __AIENGINE__
// aie_adf.hpp brings in the ADF stream API, which includes <adf.h>. That header
// is part of the Vitis ADF framework and is not present in bare-metal, IRON, or
// mlir-aie builds. Only pull it in when it is actually available, so aie_api can
// be used outside the ADF flow; when __has_include is unavailable, fall back to
// the previous behavior of including it under __AIENGINE__.
#if defined(__AIENGINE__) && (!defined(__has_include) || __has_include(<adf.h>))
#include "aie_adf.hpp"
#endif
#include "operators.hpp"
Expand Down
86 changes: 86 additions & 0 deletions include/aie_api/cascade.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: MIT
// Copyright (C) 2022 Xilinx, Inc.
// Copyright (C) 2022-2026 Advanced Micro Devices, Inc.

#pragma once

#ifndef __AIE_API_CASCADE__HPP__
#define __AIE_API_CASCADE__HPP__

#include "accum.hpp"
#include "vector.hpp"

// Adf-free accessor for the AIE core-to-core cascade.
//
// aie_api otherwise exposes the cascade only through the ADF stream API in
// aie_api/adf/, which includes <adf.h>. That header is part of the Vitis ADF
// framework and is absent in bare-metal, IRON, and mlir-aie builds, so a kernel
// compiled outside the ADF flow cannot issue a cascade put or get through
// aie_api, even though the hardware datapath is reachable through the compiler
// intrinsics directly.
//
// The accessors bridge aie_api's vector and accum types onto the compiler's
// cascade stream intrinsics put_mcd/get_scd (aie2p intrinsic layer), which
// enable the cascade with en = 1 by default. aie_api otherwise reaches those
// intrinsics only through the ADF stream types.
//
// Availability follows aie_api's usual capability model. The cascade datapath
// exists across the AIE generations, but the intrinsics are compiler and
// architecture specific (chess vs Peano; aie2/aie2p/aie2ps). __AIE_API_HAS_CASCADE__
// (detail/<arch>/config.hpp) is 1 exactly where an implementation is present:
// today aie2p under Peano. put_mcd/get_scd are the standard stream intrinsic
// names, so extending to another compiler or architecture is expected to be a
// matter of confirming the intrinsics there and setting __AIE_API_HAS_CASCADE__;
// callers that guard on the macro then pick it up with no source change.

namespace aie {

#if __AIE_API_HAS_CASCADE__

/**
* \brief Write a 16-lane int32 vector to the master cascade datapath.
*
* Adf-free: reaches the cascade without the ADF stream API.
*/
inline void cascade_out(const vector<int32_t, 16> &v)
{
put_mcd(v.to_native());
}

/**
* \brief Read a 16-lane int32 vector from the slave cascade datapath.
*/
inline vector<int32_t, 16> cascade_in_i32()
{
return get_scd_v16int32();
}

/**
* \brief Write a 16-lane acc32 accumulator to the master cascade datapath.
*
* The accumulator path is the one a fused cross-core K-reduction uses, since
* partial sums travel as accumulators. The accum to native conversion stays
* inside the public accum API through accum::to_native(), so no reinterpret_cast
* is needed and the storage representation is not assumed.
*/
inline void cascade_out(const accum<acc32, 16> &a)
{
put_mcd(a.to_native());
}

/**
* \brief Read a 16-lane acc32 accumulator from the slave cascade datapath.
*
* The native accumulator the intrinsic returns is rebuilt into an accum through
* the implicit accum(storage_t) constructor.
*/
inline accum<acc32, 16> cascade_in_acc32()
{
return accum<acc32, 16>(get_scd_v16acc32());
}

#endif // __AIE_API_HAS_CASCADE__

} // namespace aie

#endif // __AIE_API_CASCADE__HPP__
4 changes: 4 additions & 0 deletions include/aie_api/detail/aie1/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#define AIE_API_ML_VERSION 100
#define AIE_API_MATH_VERSION 100

// The adf-free cascade accessor (aie_api/cascade.hpp) is currently implemented
// only for aie2p under Peano; it is not available on this architecture.
#define __AIE_API_HAS_CASCADE__ 0

// >= 900000 is used to detect the master development branch

#define __AIE_API_REGISTER_ATTR_DEFINED__ ((__AIE_MODEL_VERSION__ >= 900000) || \
Expand Down
4 changes: 4 additions & 0 deletions include/aie_api/detail/aie2/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@

#define __AIE_API_FP32_EMULATION__ (__AIE_MODEL_VERSION__ >= 3000)

// The adf-free cascade accessor (aie_api/cascade.hpp) is currently implemented
// only for aie2p under Peano; it is not available on this architecture.
#define __AIE_API_HAS_CASCADE__ 0

#define __AIE_API_FP32_SUPPORT__ 0

#define __AIE_API_32ELEM_FLOAT_SRS_UPS__ (__AIE_MODEL_VERSION__ >= 10300)
Expand Down
11 changes: 11 additions & 0 deletions include/aie_api/detail/aie2p/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@

#define __AIE_API_HAS_COMPLEX_BFLOAT16_FIFO__ (__AIE_MODEL_VERSION__ >= 10500)

// Adf-free core-to-core cascade accessor (aie_api/cascade.hpp). The cascade
// datapath exists on the silicon, but the accessor is currently implemented
// only through the Peano __builtin_aie2p_* intrinsics, so it is available on
// aie2p under Peano. On other compilers (chess) the capability is 0 until the
// corresponding intrinsic path is added, so the accessor is simply not defined.
#ifdef __PEANO__
#define __AIE_API_HAS_CASCADE__ 1
#else
#define __AIE_API_HAS_CASCADE__ 0
#endif

#define __AIE_API_CONSTEXPR_BFLOAT16__ (__AIE_MODEL_VERSION__ >= 10900)

#define __AIE_API_COMPLEX_FP32_EMULATION__ 0
Expand Down
4 changes: 4 additions & 0 deletions include/aie_api/detail/aie2ps/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@

#define __AIE_API_FP32_EMULATION__ (__AIE_MODEL_VERSION__ >= 3000)

// The adf-free cascade accessor (aie_api/cascade.hpp) is currently implemented
// only for aie2p under Peano; it is not available on this architecture.
#define __AIE_API_HAS_CASCADE__ 0

#define __AIE_API_FP32_SUPPORT__ 0

#define __AIE_API_HAS_EXTRACT_V64BFP16__ 0
Expand Down