Skip to content

Commit f2e998d

Browse files
committed
chores: test case
2 parents 334096d + c187f97 commit f2e998d

File tree

2 files changed

+224
-15
lines changed

2 files changed

+224
-15
lines changed

src/main/TensorOperation.cpp

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ mini_jit::TensorOperation::error_t mini_jit::TensorOperation::setup(dtype_t dtyp
316316
if (dim_sizes.size() != dim_types.size() || dim_sizes.empty() || dim_types.empty())
317317
{
318318
hasSetupError = true;
319-
std::cerr << "Error: Dimension sizes and types must match and cannot be empty." << std::endl;
319+
std::cerr << "Error: Dimension sizes and types must match and cannot be empty, but got dim_sizes: " << dim_sizes.size() << ", dim_types"
320+
<< dim_types.size() << std::endl;
320321
return error_t::err_wrong_dimension;
321322
}
322323

@@ -327,7 +328,9 @@ mini_jit::TensorOperation::error_t mini_jit::TensorOperation::setup(dtype_t dtyp
327328
(isUnary(prim_last_touch) || prim_last_touch == prim_t::none) && strides_in1.empty()))))
328329
{
329330
hasSetupError = true;
330-
std::cerr << "Error: Strides must match the number of dimensions." << std::endl;
331+
std::cerr << "Error: Strides must match the number of dimensions, but got dim_sizes: " << dim_sizes.size()
332+
<< ", strides_in0: " << strides_in0.size() << ", strides_in1: " << strides_in1.size()
333+
<< ", strides_out:" << strides_out.size() << std::endl;
331334
return error_t::err_wrong_dimension; // Strides must match the number of dimensions
332335
}
333336

@@ -355,27 +358,32 @@ mini_jit::TensorOperation::error_t mini_jit::TensorOperation::setup(dtype_t dtyp
355358
if (dtype != dtype_t::fp32)
356359
{
357360
hasSetupError = true;
361+
std::cerr << "Error: data type must be fp32, but got " << static_cast<uint32_t>(dtype) << std::endl;
358362
return error_t::err_wrong_dtype;
359363
}
360364

361365
// Validate execution type order: shared -> seq -> prim
362366
if (!isSortedConfiguration(exec_types))
363367
{
364368
hasSetupError = true;
369+
std::cerr << "Error: Expected the execution types to be sorted in the order: (shared*, sequential*, primitive*)" << std::endl;
365370
return error_t::err_invalid_execution_order;
366371
}
367372

368373
if (!isValidPrimConfig(dim_types, exec_types, strides_in0, strides_out))
369374
{
370375
hasSetupError = true;
371-
std::cerr << "1: Invalid primitive configuration detected" << std::endl;
376+
std::cerr << "Error: Invalid primitive configuration detected. Expected one primitive for m and one primitive for n to exist"
377+
<< std::endl;
372378
return error_t::err_invalid_primitive_configuration;
373379
}
374380

375381
if (!isValidKDim(dim_types, exec_types, strides_in1, prim_main))
376382
{
377383
hasSetupError = true;
378-
std::cerr << "2: Invalid primitive configuration detected" << std::endl;
384+
std::cerr << "Error: Invalid primitive configuration detected. Expected to find zero primitive k dimension for unary, one primitive k "
385+
"dimension for gemm, two primitive k dimension."
386+
<< std::endl;
379387
return error_t::err_invalid_primitive_configuration;
380388
}
381389

@@ -384,7 +392,7 @@ mini_jit::TensorOperation::error_t mini_jit::TensorOperation::setup(dtype_t dtyp
384392
if (!isValidStride(dim_types, strides_in0, stride_t::out) || !isValidStride(dim_types, strides_out, stride_t::out))
385393
{
386394
hasSetupError = true;
387-
std::cerr << "3: Invalid stride configuration detected for unary" << std::endl;
395+
std::cerr << "Error: Invalid stride configuration detected for unary. Expected k-dimension to have a stride of zero." << std::endl;
388396
return error_t::err_invalid_strides;
389397
}
390398
}
@@ -394,7 +402,9 @@ mini_jit::TensorOperation::error_t mini_jit::TensorOperation::setup(dtype_t dtyp
394402
!isValidStride(dim_types, strides_out, stride_t::out))
395403
{
396404
hasSetupError = true;
397-
std::cerr << "3: Invalid stride configuration detected for brgemm" << std::endl;
405+
std::cerr << "Error: Invalid stride configuration detected for brgemm. Expected for in0 to have n-dimension stride of zero, in1 to "
406+
"have m-dimension stride of zero and out to have k-dimension stride of zero."
407+
<< std::endl;
398408
return error_t::err_invalid_strides;
399409
}
400410
}
@@ -426,12 +436,14 @@ mini_jit::TensorOperation::error_t mini_jit::TensorOperation::setup(dtype_t dtyp
426436
if (error != Unary::error_t::success)
427437
{
428438
hasSetupError = true;
439+
std::cerr << "Error: while generating the first touch unary: " << static_cast<uint32_t>(error) << std::endl;
429440
return error_t::err_invalid_first_touch_configuration;
430441
}
431442
}
432443
else
433444
{
434445
hasSetupError = true;
446+
std::cerr << "Error: Invalid type for the first touch primitive, only support zero, copy, relu." << std::endl;
435447
return error_t::err_wrong_first_touch_primitive;
436448
}
437449
}
@@ -451,18 +463,32 @@ mini_jit::TensorOperation::error_t mini_jit::TensorOperation::setup(dtype_t dtyp
451463
release_assert(indexPrimBatch != -1, "Expected a valid index for the Batch dimension but found none.");
452464
release_assert(indexPrimK != -1, "Expected a valid index for the Batch dimension but found none.");
453465

454-
std::get<Brgemm>(main_kernel)
455-
.generate(dim_sizes[indexPrimM], dim_sizes[indexPrimN], dim_sizes[indexPrimK], dim_sizes[indexPrimBatch], 0, 0, 0,
456-
Brgemm::dtype_t::fp32);
466+
Brgemm::error_t error = std::get<Brgemm>(main_kernel)
467+
.generate(dim_sizes[indexPrimM], dim_sizes[indexPrimN], dim_sizes[indexPrimK], dim_sizes[indexPrimBatch],
468+
0, 0, 0, Brgemm::dtype_t::fp32);
469+
if (error != Brgemm::error_t::success)
470+
{
471+
hasSetupError = true;
472+
std::cerr << "Error: while generating the main brgemm: " << static_cast<uint32_t>(error) << std::endl;
473+
return error_t::err_invalid_main_configuration;
474+
}
457475
}
458476
else if (prim_main == prim_t::gemm)
459477
{
460478
indexPrimK = findMatch(dim_types, exec_types, dim_t::k, exec_t::prim);
461479

462480
release_assert(indexPrimK != -1, "Expected a valid index for the K dimension but found none.");
463481

464-
std::get<Brgemm>(main_kernel)
465-
.generate(dim_sizes[indexPrimM], dim_sizes[indexPrimN], dim_sizes[indexPrimK], 1, 0, 0, 0, Brgemm::dtype_t::fp32);
482+
Brgemm::error_t error =
483+
std::get<Brgemm>(main_kernel)
484+
.generate(dim_sizes[indexPrimM], dim_sizes[indexPrimN], dim_sizes[indexPrimK], 1, 0, 0, 0, Brgemm::dtype_t::fp32);
485+
486+
if (error != Brgemm::error_t::success)
487+
{
488+
hasSetupError = true;
489+
std::cerr << "Error: while generating the main gemm: " << static_cast<uint32_t>(error) << std::endl;
490+
return error_t::err_invalid_main_configuration;
491+
}
466492
}
467493
else
468494
{
@@ -479,12 +505,14 @@ mini_jit::TensorOperation::error_t mini_jit::TensorOperation::setup(dtype_t dtyp
479505
if (error != Unary::error_t::success)
480506
{
481507
hasSetupError = true;
508+
std::cerr << "Error: while generating the main unary: " << static_cast<uint32_t>(error) << std::endl;
482509
return error_t::err_invalid_main_configuration;
483510
}
484511
}
485512
else
486513
{
487514
hasSetupError = true;
515+
std::cerr << "Error: Invalid type for the main primitive, only support zero, copy, relu, gemm, brgemm." << std::endl;
488516
return error_t::err_wrong_main_primitive;
489517
}
490518
}
@@ -501,12 +529,14 @@ mini_jit::TensorOperation::error_t mini_jit::TensorOperation::setup(dtype_t dtyp
501529
if (error != Unary::error_t::success)
502530
{
503531
hasSetupError = true;
504-
return error_t::err_invalid_main_configuration;
532+
std::cerr << "Error: while generating the last touch unary: " << static_cast<uint32_t>(error) << std::endl;
533+
return error_t::err_invalid_last_touch_configuration;
505534
}
506535
}
507536
else
508537
{
509538
hasSetupError = true;
539+
std::cerr << "Error: Invalid type for the last touch primitive, only support zero, copy, relu." << std::endl;
510540
return error_t::err_wrong_last_touch_primitive;
511541
}
512542
}

src/test/TensorOperation.test.cpp

Lines changed: 182 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,95 @@ TEST_CASE("Test tensor operation with first touch: unary (zero, relu, copy) & ma
625625
* =================================================================================================
626626
*/
627627

628+
TEST_CASE("Test tensor operation with outer loop with main kernel: unary (zero, relu, copy)", "[tensor_operation][unary][correctness]")
629+
{
630+
using namespace mini_jit;
631+
632+
auto type = GENERATE(TensorOperation::prim_t::zero, TensorOperation::prim_t::relu, TensorOperation::prim_t::copy);
633+
634+
CAPTURE(type);
635+
636+
constexpr TensorOperation::dim_t dim_types[]{TensorOperation::dim_t::n, TensorOperation::dim_t::k, TensorOperation::dim_t::c,
637+
TensorOperation::dim_t::m, TensorOperation::dim_t::k, TensorOperation::dim_t::m,
638+
TensorOperation::dim_t::m, TensorOperation::dim_t::n};
639+
constexpr TensorOperation::exec_t exec_types[]{TensorOperation::exec_t::seq, TensorOperation::exec_t::seq, TensorOperation::exec_t::seq,
640+
TensorOperation::exec_t::seq, TensorOperation::exec_t::seq, TensorOperation::exec_t::seq,
641+
TensorOperation::exec_t::prim, TensorOperation::exec_t::prim};
642+
constexpr int64_t dim_sizes[]{2, 3, 5, 8, 13, 21, 16, 16};
643+
constexpr int64_t strides_in0[]{16 * 16 * 1 * 13 * 8 * 1 * 3,
644+
0, // k-dim
645+
16 * 16 * 1 * 13 * 8,
646+
16 * 16 * 1 * 13,
647+
0, // k-dim
648+
16 * 16,
649+
1,
650+
16};
651+
constexpr int64_t strides_in1[]{0, 0, 0, 0, 0, 0, 0, 0};
652+
constexpr int64_t strides_out[]{16 * 16 * 1 * 13 * 8 * 1 * 3,
653+
0, // k-dim
654+
16 * 16 * 1 * 13 * 8,
655+
16 * 16 * 1 * 13,
656+
0, // k-dim
657+
16 * 16,
658+
1,
659+
16};
660+
661+
GenerationTest test(16, 16, 16, 1, 16 * 16 * 21 * 13 * 8 * 5 * 3 * 2, 0, 16 * 16 * 21 * 13 * 8 * 5 * 3 * 2);
662+
test.SetUp(TestInfill::Random);
663+
664+
mini_jit::TensorOperation tensor_op;
665+
TensorOperation::error_t err = tensor_op.setup(
666+
TensorOperation::dtype_t::fp32, TensorOperation::prim_t::none, type, TensorOperation::prim_t::none, std::span{dim_types},
667+
std::span{exec_types}, std::span{dim_sizes}, std::span{strides_in0}, std::span{strides_in1}, std::span{strides_out});
668+
669+
REQUIRE(err == TensorOperation::error_t::success);
670+
671+
tensor_op.execute(test.matrix_a.data(), nullptr, test.matrix_c.data());
672+
673+
UnaryType test_type = UnaryType::None;
674+
switch (type)
675+
{
676+
case TensorOperation::prim_t::zero:
677+
test_type = UnaryType::Zero;
678+
break;
679+
case TensorOperation::prim_t::copy:
680+
test_type = UnaryType::Identity;
681+
break;
682+
case TensorOperation::prim_t::relu:
683+
test_type = UnaryType::ReLu;
684+
break;
685+
default:
686+
FAIL("Could not parse the unary type!");
687+
break;
688+
}
689+
690+
for (size_t i0 = 0; i0 < dim_sizes[0]; i0++)
691+
{
692+
for (size_t i1 = 0; i1 < dim_sizes[1]; i1++)
693+
{
694+
for (size_t i2 = 0; i2 < dim_sizes[2]; i2++)
695+
{
696+
for (size_t i3 = 0; i3 < dim_sizes[3]; i3++)
697+
{
698+
for (size_t i4 = 0; i4 < dim_sizes[4]; i4++)
699+
{
700+
for (size_t i5 = 0; i5 < dim_sizes[5]; i5++)
701+
{
702+
uint64_t offset_a = i0 * strides_in0[0] + i1 * strides_in0[1] + i2 * strides_in0[2] + i3 * strides_in0[3] +
703+
i4 * strides_in0[4] + i5 * strides_in0[5];
704+
uint64_t offset_c = i0 * strides_out[0] + i1 * strides_out[1] + i2 * strides_out[2] + i3 * strides_out[3] +
705+
i4 * strides_out[4] + i5 * strides_out[5];
706+
test.naive_unary_M_N(test.matrix_a.data() + offset_a, test.matrix_c_verify.data() + offset_c, 16, 16, false, test_type);
707+
}
708+
}
709+
}
710+
}
711+
}
712+
}
713+
714+
test.verify_matmul(test.matrix_c_verify.data(), test.matrix_c.data(), test.matrix_c.size());
715+
}
716+
628717
TEST_CASE("Test tensor operation with outer loop with main kernel: gemm", "[tensor_operation][gemm][correctness]")
629718
{
630719
using namespace mini_jit;
@@ -1187,6 +1276,96 @@ TEST_CASE("Test tensor operation with outer loop with first touch: unary (zero,
11871276
* #################################################################################################
11881277
*/
11891278

1279+
TEST_CASE("Test parallel tensor operation with outer loop with main kernel: unary (zero, relu, copy)",
1280+
"[tensor_operation][unary][correctness]")
1281+
{
1282+
using namespace mini_jit;
1283+
1284+
auto type = GENERATE(TensorOperation::prim_t::zero, TensorOperation::prim_t::relu, TensorOperation::prim_t::copy);
1285+
1286+
CAPTURE(type);
1287+
1288+
constexpr TensorOperation::dim_t dim_types[]{TensorOperation::dim_t::n, TensorOperation::dim_t::m, TensorOperation::dim_t::c,
1289+
TensorOperation::dim_t::m, TensorOperation::dim_t::k, TensorOperation::dim_t::m,
1290+
TensorOperation::dim_t::m, TensorOperation::dim_t::n};
1291+
constexpr TensorOperation::exec_t exec_types[]{
1292+
TensorOperation::exec_t::shared, TensorOperation::exec_t::shared, TensorOperation::exec_t::shared, TensorOperation::exec_t::seq,
1293+
TensorOperation::exec_t::seq, TensorOperation::exec_t::seq, TensorOperation::exec_t::prim, TensorOperation::exec_t::prim};
1294+
constexpr int64_t dim_sizes[]{2, 3, 5, 8, 13, 21, 16, 16};
1295+
constexpr int64_t strides_in0[]{16 * 16 * 1 * 13 * 8 * 1 * 3,
1296+
16 * 16 * 1 * 13 * 8 * 1, // m-dim
1297+
16 * 16 * 1 * 13 * 8,
1298+
16 * 16 * 1 * 13,
1299+
0, // k-dim
1300+
16 * 16,
1301+
1,
1302+
16};
1303+
constexpr int64_t strides_in1[]{0, 0, 0, 0, 0, 0, 0, 0};
1304+
constexpr int64_t strides_out[]{16 * 16 * 1 * 13 * 8 * 1 * 3,
1305+
16 * 16 * 1 * 13 * 8 * 1, // m-dim
1306+
16 * 16 * 1 * 13 * 8,
1307+
16 * 16 * 1 * 13,
1308+
0, // k-dim
1309+
16 * 16,
1310+
1,
1311+
16};
1312+
1313+
GenerationTest test(16, 16, 16, 1, 16 * 16 * 21 * 13 * 8 * 5 * 3 * 2, 0, 16 * 16 * 21 * 13 * 8 * 5 * 3 * 2);
1314+
test.SetUp(TestInfill::Random);
1315+
1316+
mini_jit::TensorOperation tensor_op;
1317+
TensorOperation::error_t err = tensor_op.setup(
1318+
TensorOperation::dtype_t::fp32, TensorOperation::prim_t::none, type, TensorOperation::prim_t::none, std::span{dim_types},
1319+
std::span{exec_types}, std::span{dim_sizes}, std::span{strides_in0}, std::span{strides_in1}, std::span{strides_out});
1320+
1321+
REQUIRE(err == TensorOperation::error_t::success);
1322+
1323+
tensor_op.execute(test.matrix_a.data(), nullptr, test.matrix_c.data());
1324+
1325+
UnaryType test_type = UnaryType::None;
1326+
switch (type)
1327+
{
1328+
case TensorOperation::prim_t::zero:
1329+
test_type = UnaryType::Zero;
1330+
break;
1331+
case TensorOperation::prim_t::copy:
1332+
test_type = UnaryType::Identity;
1333+
break;
1334+
case TensorOperation::prim_t::relu:
1335+
test_type = UnaryType::ReLu;
1336+
break;
1337+
default:
1338+
FAIL("Could not parse the unary type!");
1339+
break;
1340+
}
1341+
1342+
for (size_t i0 = 0; i0 < dim_sizes[0]; i0++)
1343+
{
1344+
for (size_t i1 = 0; i1 < dim_sizes[1]; i1++)
1345+
{
1346+
for (size_t i2 = 0; i2 < dim_sizes[2]; i2++)
1347+
{
1348+
for (size_t i3 = 0; i3 < dim_sizes[3]; i3++)
1349+
{
1350+
for (size_t i4 = 0; i4 < dim_sizes[4]; i4++)
1351+
{
1352+
for (size_t i5 = 0; i5 < dim_sizes[5]; i5++)
1353+
{
1354+
uint64_t offset_a = i0 * strides_in0[0] + i1 * strides_in0[1] + i2 * strides_in0[2] + i3 * strides_in0[3] +
1355+
i4 * strides_in0[4] + i5 * strides_in0[5];
1356+
uint64_t offset_c = i0 * strides_out[0] + i1 * strides_out[1] + i2 * strides_out[2] + i3 * strides_out[3] +
1357+
i4 * strides_out[4] + i5 * strides_out[5];
1358+
test.naive_unary_M_N(test.matrix_a.data() + offset_a, test.matrix_c_verify.data() + offset_c, 16, 16, false, test_type);
1359+
}
1360+
}
1361+
}
1362+
}
1363+
}
1364+
}
1365+
1366+
test.verify_matmul(test.matrix_c_verify.data(), test.matrix_c.data(), test.matrix_c.size());
1367+
}
1368+
11901369
TEST_CASE("Test parallel tensor operation with outer loop with main kernel: gemm", "[tensor_operation][gemm][correctness]")
11911370
{
11921371
using namespace mini_jit;
@@ -1606,9 +1785,9 @@ TEST_CASE(
16061785
TensorOperation::dim_t::m, TensorOperation::dim_t::k, TensorOperation::dim_t::m, TensorOperation::dim_t::n, TensorOperation::dim_t::k};
16071786

16081787
constexpr TensorOperation::exec_t exec_types[]{
1609-
TensorOperation::exec_t::seq, TensorOperation::exec_t::seq, TensorOperation::exec_t::seq, TensorOperation::exec_t::seq,
1610-
TensorOperation::exec_t::seq, TensorOperation::exec_t::seq, TensorOperation::exec_t::prim, TensorOperation::exec_t::prim,
1611-
TensorOperation::exec_t::prim, TensorOperation::exec_t::prim};
1788+
TensorOperation::exec_t::shared, TensorOperation::exec_t::shared, TensorOperation::exec_t::shared, TensorOperation::exec_t::seq,
1789+
TensorOperation::exec_t::seq, TensorOperation::exec_t::seq, TensorOperation::exec_t::prim, TensorOperation::exec_t::prim,
1790+
TensorOperation::exec_t::prim, TensorOperation::exec_t::prim};
16121791

16131792
constexpr int64_t dim_sizes[]{2, 3, 5, 8, 13, 21, 3, 16, 16, 16};
16141793
constexpr int64_t strides_in0[]{0, // n-dim

0 commit comments

Comments
 (0)