Skip to content

Commit

Permalink
chore: refactor test infra (#42)
Browse files Browse the repository at this point in the history
Description TBD.

Mostly small improvements and avoiding preprocessor as much as possible.
  • Loading branch information
fvranicTT authored Mar 5, 2025
1 parent d062ff1 commit 7630a0a
Show file tree
Hide file tree
Showing 25 changed files with 181 additions and 243 deletions.
4 changes: 2 additions & 2 deletions tests/firmware/riscv/blackhole/l1_address_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once

#include <stdint.h>
#include <cstdint>

// Aux variable used to align addresses to platform specific width. BH requires 64B alignment.
#define NOC_ADDRESS_ALIGNMENT (64)
constexpr auto NOC_ADDRESS_ALIGNMENT = 64;

namespace l1_mem
{
Expand Down
2 changes: 1 addition & 1 deletion tests/firmware/riscv/wormhole/l1_address_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <cstdint>

// Aux variable used to align addresses to platform specific width. WH requires 32B alignment.
#define NOC_ADDRESS_ALIGNMENT (32)
constexpr auto NOC_ADDRESS_ALIGNMENT = 32;

namespace l1_mem
{
Expand Down
11 changes: 3 additions & 8 deletions tests/helpers/include/ckernel_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
//
// SPDX-License-Identifier: Apache-2.0

#ifndef CKERNEL_HELPER_H
#define CKERNEL_HELPER_H
#pragma once

namespace ckernel
{
Expand All @@ -16,10 +15,6 @@ volatile std::uint32_t tt_reg_ptr *mailbox_base[4] = {
reinterpret_cast<volatile std::uint32_t tt_reg_ptr *>(TENSIX_MAILBOX2_BASE),
reinterpret_cast<volatile std::uint32_t tt_reg_ptr *>(TENSIX_MAILBOX3_BASE)};

std::uint32_t cfg_state_id __attribute__((section(".bss"))) = 0; // Flip between 0 and 1 to keep state between kernel calls
std::uint32_t dest_offset_id __attribute__((section(".bss"))) = 0; // Flip between 0 and 1 to keep dest pointer between kernel calls
std::uint32_t cfg_state_id = 0; // Flip between 0 and 1 to keep state between kernel calls
std::uint32_t dest_offset_id = 0; // Flip between 0 and 1 to keep dest pointer between kernel calls
} // namespace ckernel

using namespace ckernel;

#endif
106 changes: 34 additions & 72 deletions tests/helpers/include/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,122 +2,84 @@
//
// SPDX-License-Identifier: Apache-2.0

#ifndef PARAMS_H
#define PARAMS_H
#pragma once

#include <cstdarg>
#include <cstdint>
#include <type_traits>

#define L1_ADDRESS(buffer) ((reinterpret_cast<uint32_t>(buffer) / 16) - 1)
#include "ckernel_sfpu_log.h"
#include "ckernel_sfpu_sqrt.h"
#include "ckernel_sfpu_square.h"
#include "llk_defs.h"
#include "llk_sfpu_types.h"
#include "tensix_types.h"

#ifdef LLK_TRISC_UNPACK

#ifdef FORMAT_FLOAT16_B
#define DATA_FORMAT (uint32_t)DataFormat::Float16_b
#endif
#ifdef FORMAT_FLOAT16
#define DATA_FORMAT (uint32_t)DataFormat::Float16
#endif
#ifdef FORMAT_FLOAT32
#define DATA_FORMAT (uint32_t)DataFormat::Float32
#endif
#ifdef FORMAT_INT32
#define DATA_FORMAT (uint32_t)DataFormat::Int32
#endif
#ifdef FORMAT_BFP8_B
#define DATA_FORMAT (uint32_t)DataFormat::Bfp8_b
#endif

#endif
inline uint32_t L1_ADDRESS(const volatile void* buffer)
{
return (reinterpret_cast<uint32_t>(buffer) / 16) - 1;
}

#ifdef LLK_TRISC_MATH
namespace
{
constexpr std::underlying_type_t<DataFormat> get_data_format(DataFormat format)
{
return static_cast<std::underlying_type_t<DataFormat>>(format);
}
} // namespace

#ifdef FORMAT_FLOAT16_B
#define DATA_FORMAT (uint32_t)DataFormat::Float16_b
constexpr auto DATA_FORMAT = get_data_format(DataFormat::Float16_b);
#endif
#ifdef FORMAT_FLOAT16
#define DATA_FORMAT (uint32_t)DataFormat::Float16
constexpr auto DATA_FORMAT = get_data_format(DataFormat::Float16);
#endif
#ifdef FORMAT_FLOAT32
#define DATA_FORMAT (uint32_t)DataFormat::Float32
constexpr auto DATA_FORMAT = get_data_format(DataFormat::Float32);
#endif
#ifdef FORMAT_INT32
#define DATA_FORMAT (uint32_t)DataFormat::Int32
constexpr auto DATA_FORMAT = get_data_format(DataFormat::Int32);
#endif
#ifdef FORMAT_BFP8_B
#define DATA_FORMAT (uint32_t)DataFormat::Bfp8_b
constexpr auto DATA_FORMAT = get_data_format(DataFormat::Bfp8_b);
#endif

#ifdef ELTWISE_BINARY_ADD
#define ELTWISE_BINARY_OP EltwiseBinaryType::ELWADD
constexpr auto ELTWISE_BINARY_OP = ckernel::EltwiseBinaryType::ELWADD;
#endif
#ifdef ELTWISE_BINARY_SUB
#define ELTWISE_BINARY_OP EltwiseBinaryType::ELWSUB
constexpr auto ELTWISE_BINARY_OP = ckernel::EltwiseBinaryType::ELWSUB;
#endif
#ifdef ELTWISE_BINARY_MUL
#define ELTWISE_BINARY_OP EltwiseBinaryType::ELWMUL
constexpr auto ELTWISE_BINARY_OP = ckernel::EltwiseBinaryType::ELWMUL;
#endif
// TO BE IMPLEMENTED IN LLKs
#ifdef ELTWISE_BINARY_DIV
#define ELTWISE_BINARY_OP EltwiseBinaryType::ELWDIV
constexpr auto ELTWISE_BINARY_OP = ckernel::EltwiseBinaryType::ELWDIV;
#endif
#ifdef ELTWISE_BINARY_LESS
#define ELTWISE_BINARY_OP EltwiseBinaryType::ELWLESS
constexpr auto ELTWISE_BINARY_OP = ckernel::EltwiseBinaryType::ELWLESS;
#endif

// SFPU operation macros

#ifdef SFPU_OP_SQRT
#define SFPU_OPERATION SfpuType::sqrt
#define SFPU_CALLS \
_init_sqrt_<APPROX_MODE>(); \
_calculate_sqrt_<APPROX_MODE, 0, 10>(10);
constexpr auto SFPU_OPERATION = SfpuType::sqrt;
#endif
#ifdef SFPU_OP_LOG
#define SFPU_OPERATION SfpuType::log
#define SFPU_CALLS \
_init_log_<APPROX_MODE>(); \
_calculate_log_<APPROX_MODE, false, 10>(10, 0);
constexpr auto SFPU_OPERATION = SfpuType::log;
#endif
#ifdef SFPU_OP_SQUARE
#define SFPU_OPERATION SfpuType::square
#define SFPU_CALLS _calculate_square_<APPROX_MODE, 10>(10);
constexpr auto SFPU_OPERATION = SfpuType::square;
#endif

#endif

#ifdef LLK_TRISC_PACK

inline void process_addresses(volatile uint32_t* buffer_Dest[], int n, int first, ...)
{
buffer_Dest[0] = (volatile uint32_t*)first;
buffer_Dest[0] = reinterpret_cast<volatile uint32_t*>(first);

va_list args;
va_start(args, first);
for (int i = 1; i < n; ++i)
{
int num = va_arg(args, int);
buffer_Dest[i] = (volatile uint32_t*)num;
buffer_Dest[i] = reinterpret_cast<volatile uint32_t*>(num);
}
va_end(args);
}

#ifdef FORMAT_FLOAT16_B
#define DATA_FORMAT (uint32_t)DataFormat::Float16_b
#endif
#ifdef FORMAT_FLOAT16
#define DATA_FORMAT (uint32_t)DataFormat::Float16
#endif
#ifdef FORMAT_FLOAT32
#define DATA_FORMAT (uint32_t)DataFormat::Float32
#endif
#ifdef FORMAT_INT32
#define DATA_FORMAT (uint32_t)DataFormat::Int32
#endif
#ifdef FORMAT_BFP8_B
#define DATA_FORMAT (uint32_t)DataFormat::Bfp8_b
#endif

#endif

#endif
19 changes: 10 additions & 9 deletions tests/helpers/src/trisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//
// SPDX-License-Identifier: Apache-2.0

#include <algorithm>
#include <cstdint>

#include "ckernel.h"
Expand All @@ -16,19 +17,15 @@
int main()
{
#ifdef LLK_TRISC_UNPACK
volatile std::uint32_t* mailbox = (volatile std::uint32_t*)(0x19FFC);
volatile std::uint32_t* mailbox = reinterpret_cast<volatile std::uint32_t*>(0x19FFC);
#elif defined(LLK_TRISC_MATH)
volatile std::uint32_t* mailbox = (volatile std::uint32_t*)(0x19FF8);
volatile std::uint32_t* mailbox = reinterpret_cast<volatile std::uint32_t*>(0x19FF8);
#elif defined(LLK_TRISC_PACK)
volatile std::uint32_t* mailbox = (volatile std::uint32_t*)(0x19FF4);
volatile std::uint32_t* mailbox = reinterpret_cast<volatile std::uint32_t*>(0x19FF4);
#endif

*mailbox = 0x2; // write value different than 1 to mailbox to indicate kernel is running

for (int i = 0; i < 64; i++)
{
ckernel::regfile[i] = 0;
}
std::fill(ckernel::regfile, ckernel::regfile + 64, 0);

ckernel::reset_cfg_state_id();
ckernel::reset_dest_offset_id();
Expand All @@ -38,7 +35,11 @@ int main()

*mailbox = ckernel::KERNEL_COMPLETE; // 0x1

for (;;)
// Use a volatile variable to prevent the compiler from optimizing away the loop
volatile bool run = true;

// Infinite loop
while (run)
{
}
}
2 changes: 1 addition & 1 deletion tests/python_tests/helpers/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def run_elf_files(testname, core_loc="0,0", run_brisc=True):
# and now cores are run in revese order PACK, MATH, UNOPACK
# Once that issue is reolved with tt-exalens code will be returned to normal for loop

for i in range(2, -1, -1):
for i in reversed(range(3)):
run_elf(f"{ELF_LOCATION}{testname}_trisc{i}.elf", core_loc, risc_id=i + 1)


Expand Down
73 changes: 31 additions & 42 deletions tests/python_tests/helpers/pack.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,20 @@ def flatten_list(sublists):


def int_to_bytes_list(n):
binary_str = bin(n)[2:].zfill(32)
return [int(binary_str[i : i + 8], 2) for i in range(0, 32, 8)]


def float16_to_bytes(value):
float16_value = torch.tensor(value, dtype=torch.float16)
packed_bytes = struct.pack(">e", float16_value.item())
return list(packed_bytes) + [0] * (4 - len(packed_bytes))


def bfloat16_to_bytes(number):
number_unpacked = struct.unpack("!I", struct.pack("!f", number))[0]
res_masked = number_unpacked & 0xFFFF0000
return int_to_bytes_list(res_masked)
return [(n >> (8 * i)) & 0xFF for i in range(3, -1, -1)]


def fp32_to_bytes(number):
number_unpacked = struct.unpack("!I", struct.pack("!f", number))[0]
return int_to_bytes_list(number_unpacked)


def int32_to_bytes(number):
number = int(number)
number_unpacked = struct.unpack("!I", struct.pack("!I", number))[0]
return int_to_bytes_list(number_unpacked)


def bfloat16_to_binary(value):
float_value = value.to(torch.float32).item()
bfloat16_bytes = bfloat16_to_bytes(float_value)
return f"{bfloat16_bytes[0]:08b}{bfloat16_bytes[1]:08b}"


def pack_bfp16(torch_tensor):
def bfloat16_to_bytes(number):
number_unpacked = struct.unpack("!I", struct.pack("!f", number))[0]
res_masked = number_unpacked & 0xFFFF0000
return int_to_bytes_list(res_masked)

packed_bytes = []
for i in range(0, len(torch_tensor), 2):
half1 = bfloat16_to_bytes(torch_tensor[i])
Expand All @@ -55,29 +35,44 @@ def pack_bfp16(torch_tensor):


def pack_fp16(torch_tensor):
def float16_to_bytes(value):
packed_bytes = struct.pack("<e", value)
return list(packed_bytes)

packed_bytes = []
for i in range(0, len(torch_tensor), 2):
half1 = float16_to_bytes(torch_tensor[i])
half2 = float16_to_bytes(torch_tensor[i + 1])
packed_bytes.extend([half1[0:2][::-1], half2[0:2][::-1]][::-1])
packed_bytes.extend([half1[0:2], half2[0:2]][::-1])
return flatten_list(packed_bytes)


def pack_fp32(torch_tensor):
packed_bytes = []
for i in range(0, len(torch_tensor)):
packed_bytes.append(fp32_to_bytes(torch_tensor[i])[::-1])
def fp32_to_bytes(number):
return list(struct.pack("<f", number))

packed_bytes = [None] * len(torch_tensor)
for i in range(len(torch_tensor)):
packed_bytes[i] = fp32_to_bytes(torch_tensor[i])
return flatten_list(packed_bytes)


def pack_int32(torch_tensor):
packed_bytes = []
for i in range(0, len(torch_tensor)):
packed_bytes.append(int32_to_bytes(torch_tensor[i])[::-1])
def int32_to_bytes(number):
return list(struct.pack("<I", number))

packed_bytes = [None] * len(torch_tensor)
for i in range(len(torch_tensor)):
packed_bytes[i] = int32_to_bytes(torch_tensor[i])
return flatten_list(packed_bytes)


def float_to_bfp8_block(block):
def bfloat16_to_binary(value):
float_value = struct.unpack("!I", struct.pack("!f", value))[0]
bfloat16_value = (float_value & 0xFFFF0000) >> 16
return f"{(bfloat16_value >> 8) & 0xFF:08b}{bfloat16_value & 0xFF:08b}"

exponents = []
mantissas = []
signs = []
Expand Down Expand Up @@ -109,22 +104,16 @@ def float_to_bfp8_block(block):


def pack_bfp8_b(tensor, block_size=16):

flattened_tensor = tensor.flatten()
num_blocks = len(flattened_tensor) // block_size
blocks = [
flattened_tensor[i * block_size : (i + 1) * block_size]
for i in range(num_blocks)
]

exponents = []
mantissas = []

for block in blocks:
for i in range(num_blocks):
block = flattened_tensor[i * block_size : (i + 1) * block_size]
shared_exponent, bfp8_mantissas = float_to_bfp8_block(block)
exponents.append(shared_exponent)
mantissas.extend(bfp8_mantissas)

bfp8_result = exponents + mantissas

return bfp8_result
return exponents + mantissas
Loading

0 comments on commit 7630a0a

Please sign in to comment.