Skip to content

Commit 5f7ac3b

Browse files
cc_model_filename no longer ignored
1 parent eb2f06b commit 5f7ac3b

4 files changed

Lines changed: 206 additions & 1 deletion

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/build
2+
/build_test
23
/.vscode
34
*.so
45
*__pycache__/

src/model_config_utils.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1273,7 +1273,8 @@ AutoCompleteBackendFields(
12731273
}
12741274
}
12751275
if (config->backend() == kPythonBackend) {
1276-
if (config->default_model_filename().empty()) {
1276+
if (config->default_model_filename().empty() &&
1277+
config->cc_model_filenames().empty()) {
12771278
config->set_default_model_filename(kPythonFilename);
12781279
}
12791280
return Status::Success;

src/test/CMakeLists.txt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,56 @@ install(
439439
RUNTIME DESTINATION bin
440440
)
441441

442+
#
443+
# Unit test for AutoCompleteBackendFields in model_config_utils
444+
#
445+
add_executable(
446+
model_config_utils_test
447+
model_config_utils_test.cc
448+
../model_config_utils.cc
449+
../status.cc
450+
../filesystem/api.cc
451+
../model_config_utils.h
452+
../status.h
453+
../filesystem/api.h
454+
)
455+
456+
set_target_properties(
457+
model_config_utils_test
458+
PROPERTIES
459+
SKIP_BUILD_RPATH TRUE
460+
BUILD_WITH_INSTALL_RPATH TRUE
461+
INSTALL_RPATH_USE_LINK_PATH FALSE
462+
INSTALL_RPATH ""
463+
)
464+
465+
target_include_directories(
466+
model_config_utils_test
467+
PRIVATE
468+
${CMAKE_CURRENT_SOURCE_DIR}/..
469+
${CMAKE_CURRENT_SOURCE_DIR}/../../include
470+
${GTEST_INCLUDE_DIRS}
471+
${Boost_INCLUDE_DIRS}
472+
)
473+
474+
target_link_libraries(
475+
model_config_utils_test
476+
PRIVATE
477+
triton-common-error # from repo-common
478+
triton-common-model-config # from repo-common
479+
triton-common-json # from repo-common
480+
triton-common-logging # from repo-common
481+
proto-library # from repo-common
482+
GTest::gtest
483+
GTest::gtest_main
484+
protobuf::libprotobuf
485+
)
486+
487+
install(
488+
TARGETS model_config_utils_test
489+
RUNTIME DESTINATION bin
490+
)
491+
442492

443493
if(${TRITON_ENABLE_METRICS})
444494
#
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// Copyright 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
//
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions
5+
// are met:
6+
// * Redistributions of source code must retain the above copyright
7+
// notice, this list of conditions and the following disclaimer.
8+
// * Redistributions in binary form must reproduce the above copyright
9+
// notice, this list of conditions and the following disclaimer in the
10+
// documentation and/or other materials provided with the distribution.
11+
// * Neither the name of NVIDIA CORPORATION nor the names of its
12+
// contributors may be used to endorse or promote products derived
13+
// from this software without specific prior written permission.
14+
//
15+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
16+
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19+
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20+
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23+
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
#include "model_config_utils.h"
28+
29+
#include <sys/stat.h>
30+
31+
#include <fstream>
32+
#include <string>
33+
34+
#include "constants.h"
35+
#include "filesystem/api.h"
36+
#include "gtest/gtest.h"
37+
38+
namespace tc = triton::core;
39+
40+
namespace {
41+
42+
// Helper to create a temporary model directory with a version subdirectory
43+
// and an optional file inside it.
44+
class TempModelDir {
45+
public:
46+
TempModelDir()
47+
{
48+
auto status =
49+
tc::MakeTemporaryDirectory(tc::FileSystemType::LOCAL, &root_path_);
50+
EXPECT_TRUE(status.IsOk()) << status.AsString();
51+
}
52+
53+
~TempModelDir()
54+
{
55+
// Best-effort cleanup
56+
std::string cmd = "rm -rf " + root_path_;
57+
(void)system(cmd.c_str());
58+
}
59+
60+
// Create version subdir (e.g., "1") and optionally place a file in it.
61+
void AddVersionWithFile(
62+
const std::string& version, const std::string& filename)
63+
{
64+
std::string version_dir = tc::JoinPath({root_path_, version});
65+
mkdir(version_dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
66+
if (!filename.empty()) {
67+
std::ofstream f(tc::JoinPath({version_dir, filename}));
68+
f << "# placeholder";
69+
}
70+
}
71+
72+
const std::string& Path() const { return root_path_; }
73+
74+
private:
75+
std::string root_path_;
76+
};
77+
78+
class AutoCompleteBackendFieldsTest : public ::testing::Test {};
79+
80+
// When backend is "python" and default_model_filename is empty and
81+
// cc_model_filenames is empty, default_model_filename should be set to
82+
// "model.py".
83+
TEST_F(AutoCompleteBackendFieldsTest, PythonBackendSetsDefaultFilename)
84+
{
85+
TempModelDir dir;
86+
dir.AddVersionWithFile("1", "model.py");
87+
88+
inference::ModelConfig config;
89+
config.set_backend("python");
90+
// default_model_filename and cc_model_filenames are both empty
91+
92+
auto status = tc::AutoCompleteBackendFields("test_model", dir.Path(), &config);
93+
ASSERT_TRUE(status.IsOk()) << status.AsString();
94+
EXPECT_EQ(config.default_model_filename(), "model.py");
95+
}
96+
97+
// When backend is "python" and default_model_filename is empty but
98+
// cc_model_filenames is populated, default_model_filename should NOT be
99+
// auto-filled to "model.py".
100+
TEST_F(
101+
AutoCompleteBackendFieldsTest,
102+
PythonBackendSkipsDefaultFilenameWhenCcModelFilenamesSet)
103+
{
104+
TempModelDir dir;
105+
dir.AddVersionWithFile("1", "custom_model.py");
106+
107+
inference::ModelConfig config;
108+
config.set_backend("python");
109+
(*config.mutable_cc_model_filenames())["gpu"] = "custom_model.py";
110+
// default_model_filename is empty, cc_model_filenames is set
111+
112+
auto status = tc::AutoCompleteBackendFields("test_model", dir.Path(), &config);
113+
ASSERT_TRUE(status.IsOk()) << status.AsString();
114+
EXPECT_EQ(config.default_model_filename(), "")
115+
<< "default_model_filename should remain empty when cc_model_filenames "
116+
"is set";
117+
}
118+
119+
// When backend is "python" and default_model_filename is already set,
120+
// it should be preserved regardless of cc_model_filenames.
121+
TEST_F(
122+
AutoCompleteBackendFieldsTest,
123+
PythonBackendPreservesExplicitDefaultFilename)
124+
{
125+
TempModelDir dir;
126+
dir.AddVersionWithFile("1", "my_model.py");
127+
128+
inference::ModelConfig config;
129+
config.set_backend("python");
130+
config.set_default_model_filename("my_model.py");
131+
132+
auto status = tc::AutoCompleteBackendFields("test_model", dir.Path(), &config);
133+
ASSERT_TRUE(status.IsOk()) << status.AsString();
134+
EXPECT_EQ(config.default_model_filename(), "my_model.py");
135+
}
136+
137+
// When backend is empty but version dir contains model.py, backend should be
138+
// auto-detected as "python" and default_model_filename set to "model.py".
139+
TEST_F(AutoCompleteBackendFieldsTest, AutoDetectPythonBackendFromModelFile)
140+
{
141+
TempModelDir dir;
142+
dir.AddVersionWithFile("1", "model.py");
143+
144+
inference::ModelConfig config;
145+
// backend, platform, default_model_filename all empty
146+
147+
auto status = tc::AutoCompleteBackendFields("test_model", dir.Path(), &config);
148+
ASSERT_TRUE(status.IsOk()) << status.AsString();
149+
EXPECT_EQ(config.backend(), "python");
150+
EXPECT_EQ(config.default_model_filename(), "model.py");
151+
}
152+
153+
} // namespace

0 commit comments

Comments
 (0)