Skip to content
Merged
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: 2 additions & 0 deletions .github/workflows/windows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ jobs:
-DCTEST_TIMEOUT=5000
cd build
cmake --build . --target driver
# migraphx_cpu.dll loads dnnl.dll at runtime, which lives in the cget prefix
export PATH="$PATH:$(cygpath -u "$GITHUB_WORKSPACE")/cget/bin:$(cygpath -u "$GITHUB_WORKSPACE")/cget/lib"
ctest -j 8 --output-on-failure --timeout 5000 -E 'test_bf16|test_float32|test_half|test_logger_test|test_schedule_test|test_ref'


Expand Down
36 changes: 35 additions & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ def setupdocker(Map conf) {
return docker_opts
}

// The driver exits 0 even when verification fails, so check its log as well as
// its exit status: a crash or sanitizer error after the success message must fail.
def driver_test(String driver) {
return """
status=0
${driver} verify --test > driver.log 2>&1 || status=\$?
cat driver.log
test \$status -eq 0
grep -q "verification passed successfully" driver.log
"""
}

def cmake_build = { bconf ->
def compiler = bconf.get("compiler", "/opt/rocm/llvm/bin/clang++")
def flags = bconf.get("flags", "")
Expand Down Expand Up @@ -103,6 +115,7 @@ def cmake_build = { bconf ->
git diff-index --quiet HEAD || (echo "Generated files are different. Please run make generate and commit the changes." && exit 1)
make -j\$(nproc) ${targets} VERBOSE=1
if [ -n "\$(ls ./*.deb 2>/dev/null)" ]; then md5sum ./*.deb; fi
${driver_test('./bin/migraphx-driver')}
"""
echo cmd
sh cmd
Expand Down Expand Up @@ -295,6 +308,11 @@ def setuppackage = {
unstash 'migraphx-package'
}

def setupstaticdriver = {
sh 'rm -rf ./build/bin'
unstash 'migraphx-static-driver'
}

pipeline {
agent {
label "(rocmtest || migraphx)"
Expand Down Expand Up @@ -423,8 +441,9 @@ pipeline {
}
steps {
script {
rocmtest([:]) {
rocmtest(skip_also_requires: ['Static Driver Tests']) {
cmake_build(skip_package: true, flags: "-DBUILD_SHARED_LIBS=Off -DMIGRAPHX_ENABLE_PYTHON=Off -DCMAKE_BUILD_TYPE=release -DGPU_TARGETS='${getgputargets()}'")
stash includes: 'build/bin/migraphx-driver', name: 'migraphx-static-driver'
}
}
}
Expand Down Expand Up @@ -565,6 +584,21 @@ pipeline {
}
}
}

stage('Static Driver Tests') {
agent {
label rocmnodename('mi300+')
}
steps {
script {
rocmtest(setup: setupstaticdriver, image: DOCKER_IMAGE_ORT, imageTag: env.IMAGE_TAG_ORT) {
// The ORT image only has ROCm installed, so the static
// driver must run without anything from rbuild or the build tree.
sh driver_test('./build/bin/migraphx-driver')
}
}
}
}
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/argument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,13 @@ argument::data_t argument::data_t::from_args(const std::vector<argument>& args)

argument argument::copy() const
{
if(m_shape.type() == shape::tuple_type)
{
auto subs = this->get_sub_objects();
std::transform(
subs.begin(), subs.end(), subs.begin(), [](const auto& sub) { return sub.copy(); });
return argument{subs};
}
argument result{this->get_shape()};
auto* src = this->data();
std::copy(src, src + this->get_shape().bytes(), result.data());
Expand Down
5 changes: 4 additions & 1 deletion src/program_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,10 @@ std::vector<argument> run_target(program p,
std::vector<argument> output(gpu_out.size());
log::info() << p;
std::transform(gpu_out.begin(), gpu_out.end(), output.begin(), [&](const auto& argu) {
return options.compile.offload_copy ? argu : t.copy_from(argu);
auto host = options.compile.offload_copy ? argu : t.copy_from(argu);
// The outputs can be views into memory owned by the program (eg the cpu
// target), so copy them to outlive it.
return host.copy();
});
return output;
}
Expand Down
12 changes: 12 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ if(MIGRAPHX_ENABLE_GPU)
add_subdirectory(gpu/kernels)
endif()

if(MIGRAPHX_ENABLE_CPU)
# cpu tests
file(GLOB CPU_TESTS CONFIGURE_DEPENDS cpu/*.cpp)

foreach(TEST ${CPU_TESTS})
get_filename_component(BASE_NAME ${TEST} NAME_WE)
rocm_add_test_executable(test_cpu_${BASE_NAME} ${TEST})
rocm_clang_tidy_check(test_cpu_${BASE_NAME})
target_link_libraries(test_cpu_${BASE_NAME} migraphx_lazy_ref migraphx_cpu)
endforeach()
endif()

if(MIGRAPHX_ENABLE_FPGA)
# fpga tests
file(GLOB FPGA_TESTS CONFIGURE_DEPENDS fpga/*.cpp)
Expand Down
26 changes: 25 additions & 1 deletion test/argument_test.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All rights reserved.
* Copyright (c) 2015-2026 Advanced Micro Devices, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -254,4 +254,28 @@ TEST_CASE(argument_share)
EXPECT(a4.data() == a3.data());
}

TEST_CASE(argument_copy)
{
migraphx::shape s{migraphx::shape::int64_type, {3}};
std::vector<std::int64_t> buffer{1, 2, 3};
migraphx::argument a1(s, buffer.data());
auto a2 = a1.copy();
EXPECT(a1.data() != a2.data());
EXPECT(a1 == a2);
// The write is read back through a1, which aliases the buffer
// cppcheck-suppress unreadVariable
buffer[0] = 4;
EXPECT(a1 != a2);
EXPECT(a2.to_vector<std::int64_t>() == std::vector<std::int64_t>{1, 2, 3});
}

TEST_CASE(argument_copy_tuple)
{
auto a1 = make_tuple(3, 3.0);
auto a2 = a1.copy();
EXPECT(a1 == a2);
EXPECT(a1.get_sub_objects()[0].data() != a2.get_sub_objects()[0].data());
EXPECT(a1.get_sub_objects()[1].data() != a2.get_sub_objects()[1].data());
}

int main(int argc, const char* argv[]) { test::run(argc, argv); }
45 changes: 45 additions & 0 deletions test/cpu/program_verify.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2015-2026 Advanced Micro Devices, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <migraphx/cpu/target.hpp>
#include <migraphx/make_op.hpp>
#include <migraphx/program.hpp>
#include <migraphx/program_verify.hpp>
#include <test.hpp>

// The cpu outputs are views into memory owned by the compiled program, so they
// must stay valid until they are compared with the ref outputs.
TEST_CASE(verify_program_outputs)
{
migraphx::program p;
auto* mm = p.get_main_module();
auto a = mm->add_parameter("a", migraphx::shape{migraphx::shape::float_type, {4, 5}});
auto b = mm->add_parameter("b", migraphx::shape{migraphx::shape::float_type, {5, 3}});
mm->add_return({mm->add_instruction(migraphx::make_op("dot"), a, b)});

auto result = migraphx::verify::verify_program(
p, migraphx::cpu::target{}, migraphx::verify::program_mode::outputs);
EXPECT(result.passed());
}

int main(int argc, const char* argv[]) { test::run(argc, argv); }
Loading