|
164 | 164 | #include "ConvWithAsymmetricPadding_FromONNX_GPU_ALPAKA.hxx" |
165 | 165 | #include "input_models/references/ConvWithAsymmetricPadding.ref.hxx" |
166 | 166 |
|
| 167 | +#include "ConvWithBias_FromONNX_GPU_ALPAKA.hxx" |
| 168 | +#include "input_models/references/ConvWithBias.ref.hxx" |
| 169 | + |
| 170 | +#include "Conv1d_FromONNX_GPU_ALPAKA.hxx" |
| 171 | +#include "input_models/references/Conv1d.ref.hxx" |
| 172 | + |
| 173 | +#include "Conv3d_FromONNX_GPU_ALPAKA.hxx" |
| 174 | +#include "input_models/references/Conv3d.ref.hxx" |
| 175 | + |
167 | 176 | #include "BatchNorm_FromONNX_GPU_ALPAKA.hxx" |
168 | 177 | #include "BatchNormRelu_FromONNX_GPU_ALPAKA.hxx" |
169 | 178 |
|
@@ -2442,6 +2451,121 @@ TEST_F(SofieAlpakaTest, ConvWithAsymmetricPadding) |
2442 | 2451 | } |
2443 | 2452 | } |
2444 | 2453 |
|
| 2454 | +// Exercises the Conv GPU bias path (BiasBroadcastKernel + GEMM beta=1). The existing |
| 2455 | +// ConvWith* models have no bias input, so the bias kernel was never run. Two output |
| 2456 | +// channels with distinct biases (10, 100) make a wrong-channel broadcast visible. |
| 2457 | +TEST_F(SofieAlpakaTest, ConvWithBias) |
| 2458 | +{ |
| 2459 | + constexpr float TOLERANCE = DEFAULT_TOLERANCE; |
| 2460 | + |
| 2461 | + // x[1,1,5,5] = iota 0..24 |
| 2462 | + std::vector<float> input(25); |
| 2463 | + std::iota(input.begin(), input.end(), 0.0f); |
| 2464 | + |
| 2465 | + auto input_h = alpaka::allocBuf<float, Idx>(host, Ext1D::all(Idx{input.size()})); |
| 2466 | + float* input_ptr = reinterpret_cast<float*>(alpaka::getPtrNative(input_h)); |
| 2467 | + for (Idx i = 0; i < input.size(); ++i) input_ptr[i] = input[i]; |
| 2468 | + |
| 2469 | + auto input_d = alpaka::allocBuf<float, Idx>(device, Ext1D::all(Idx{input.size()})); |
| 2470 | + alpaka::memcpy(queue, input_d, input_h); |
| 2471 | + alpaka::wait(queue); |
| 2472 | + |
| 2473 | + auto result_h = alpaka::allocBuf<float, Idx>(host, Ext1D::all(Idx{sizeof(ConvWithBias_ExpectedOutput::all_ones) / sizeof(float)})); |
| 2474 | + |
| 2475 | + { |
| 2476 | + SOFIE_ConvWithBias::Session<alpaka::TagGpuCudaRt> session("ConvWithBias_FromONNX_GPU_ALPAKA.dat"); |
| 2477 | + auto result = session.infer(input_d); |
| 2478 | + alpaka::wait(queue); |
| 2479 | + cudaDeviceSynchronize(); |
| 2480 | + alpaka::memcpy(queue, result_h, result); |
| 2481 | + alpaka::wait(queue); |
| 2482 | + } |
| 2483 | + |
| 2484 | + float* res_ptr = reinterpret_cast<float*>(alpaka::getPtrNative(result_h)); |
| 2485 | + float *correct = ConvWithBias_ExpectedOutput::all_ones; |
| 2486 | + constexpr size_t nOut_bias = sizeof(ConvWithBias_ExpectedOutput::all_ones) / sizeof(float); |
| 2487 | + |
| 2488 | + for (size_t i = 0; i < nOut_bias; ++i) { |
| 2489 | + EXPECT_LE(std::abs(res_ptr[i] - correct[i]), TOLERANCE) << "i=" << i; |
| 2490 | + } |
| 2491 | +} |
| 2492 | + |
| 2493 | +// Exercises the Conv GPU 1D path (fDim==1 branches in weight-vec/im2col). All other |
| 2494 | +// alpaka Conv models are 2D. x[1,2,7], W[3,2,3] iota weights, bias [1,2,3], pads [1,1]. |
| 2495 | +TEST_F(SofieAlpakaTest, Conv1d) |
| 2496 | +{ |
| 2497 | + constexpr float TOLERANCE = DEFAULT_TOLERANCE; |
| 2498 | + |
| 2499 | + // x[1,2,7] = iota 0..13 |
| 2500 | + std::vector<float> input(14); |
| 2501 | + std::iota(input.begin(), input.end(), 0.0f); |
| 2502 | + |
| 2503 | + auto input_h = alpaka::allocBuf<float, Idx>(host, Ext1D::all(Idx{input.size()})); |
| 2504 | + float* input_ptr = reinterpret_cast<float*>(alpaka::getPtrNative(input_h)); |
| 2505 | + for (Idx i = 0; i < input.size(); ++i) input_ptr[i] = input[i]; |
| 2506 | + |
| 2507 | + auto input_d = alpaka::allocBuf<float, Idx>(device, Ext1D::all(Idx{input.size()})); |
| 2508 | + alpaka::memcpy(queue, input_d, input_h); |
| 2509 | + alpaka::wait(queue); |
| 2510 | + |
| 2511 | + auto result_h = alpaka::allocBuf<float, Idx>(host, Ext1D::all(Idx{sizeof(Conv1d_ExpectedOutput::all_ones) / sizeof(float)})); |
| 2512 | + |
| 2513 | + { |
| 2514 | + SOFIE_Conv1d::Session<alpaka::TagGpuCudaRt> session("Conv1d_FromONNX_GPU_ALPAKA.dat"); |
| 2515 | + auto result = session.infer(input_d); |
| 2516 | + alpaka::wait(queue); |
| 2517 | + cudaDeviceSynchronize(); |
| 2518 | + alpaka::memcpy(queue, result_h, result); |
| 2519 | + alpaka::wait(queue); |
| 2520 | + } |
| 2521 | + |
| 2522 | + float* res_ptr = reinterpret_cast<float*>(alpaka::getPtrNative(result_h)); |
| 2523 | + float *correct = Conv1d_ExpectedOutput::all_ones; |
| 2524 | + constexpr size_t nOut_conv1d = sizeof(Conv1d_ExpectedOutput::all_ones) / sizeof(float); |
| 2525 | + |
| 2526 | + for (size_t i = 0; i < nOut_conv1d; ++i) { |
| 2527 | + EXPECT_LE(std::abs(res_ptr[i] - correct[i]), TOLERANCE) << "i=" << i; |
| 2528 | + } |
| 2529 | +} |
| 2530 | + |
| 2531 | +// Exercises the Conv GPU 3D path (fDim>2 depth branches + depth handling in im2col). |
| 2532 | +// x[1,1,3,4,4], W[2,1,2,3,3] iota weights, bias [5,50], kernel (2,3,3), pads h/w by 1. |
| 2533 | +TEST_F(SofieAlpakaTest, Conv3d) |
| 2534 | +{ |
| 2535 | + constexpr float TOLERANCE = DEFAULT_TOLERANCE; |
| 2536 | + |
| 2537 | + // x[1,1,3,4,4] = iota 0..47 |
| 2538 | + std::vector<float> input(48); |
| 2539 | + std::iota(input.begin(), input.end(), 0.0f); |
| 2540 | + |
| 2541 | + auto input_h = alpaka::allocBuf<float, Idx>(host, Ext1D::all(Idx{input.size()})); |
| 2542 | + float* input_ptr = reinterpret_cast<float*>(alpaka::getPtrNative(input_h)); |
| 2543 | + for (Idx i = 0; i < input.size(); ++i) input_ptr[i] = input[i]; |
| 2544 | + |
| 2545 | + auto input_d = alpaka::allocBuf<float, Idx>(device, Ext1D::all(Idx{input.size()})); |
| 2546 | + alpaka::memcpy(queue, input_d, input_h); |
| 2547 | + alpaka::wait(queue); |
| 2548 | + |
| 2549 | + auto result_h = alpaka::allocBuf<float, Idx>(host, Ext1D::all(Idx{sizeof(Conv3d_ExpectedOutput::all_ones) / sizeof(float)})); |
| 2550 | + |
| 2551 | + { |
| 2552 | + SOFIE_Conv3d::Session<alpaka::TagGpuCudaRt> session("Conv3d_FromONNX_GPU_ALPAKA.dat"); |
| 2553 | + auto result = session.infer(input_d); |
| 2554 | + alpaka::wait(queue); |
| 2555 | + cudaDeviceSynchronize(); |
| 2556 | + alpaka::memcpy(queue, result_h, result); |
| 2557 | + alpaka::wait(queue); |
| 2558 | + } |
| 2559 | + |
| 2560 | + float* res_ptr = reinterpret_cast<float*>(alpaka::getPtrNative(result_h)); |
| 2561 | + float *correct = Conv3d_ExpectedOutput::all_ones; |
| 2562 | + constexpr size_t nOut_conv3d = sizeof(Conv3d_ExpectedOutput::all_ones) / sizeof(float); |
| 2563 | + |
| 2564 | + for (size_t i = 0; i < nOut_conv3d; ++i) { |
| 2565 | + EXPECT_LE(std::abs(res_ptr[i] - correct[i]), TOLERANCE) << "i=" << i; |
| 2566 | + } |
| 2567 | +} |
| 2568 | + |
2445 | 2569 | TEST_F(SofieAlpakaTest, BatchNormalization) |
2446 | 2570 | { |
2447 | 2571 | constexpr float TOLERANCE = DEFAULT_TOLERANCE; |
|
0 commit comments