tests compile but not link
Some checks failed
CI/CD Pipeline / Code Linting (push) Failing after 21s
CI/CD Pipeline / Build and Test (Debug, clang, ubuntu-latest) (push) Failing after 5m17s
CI/CD Pipeline / Build and Test (Debug, gcc, ubuntu-latest) (push) Failing after 5m58s
CI/CD Pipeline / Build and Test (Release, clang, ubuntu-20.04) (push) Failing after 6m4s
CI/CD Pipeline / Build and Test (Release, clang, ubuntu-latest) (push) Failing after 5m16s
CI/CD Pipeline / Build and Test (Release, gcc, ubuntu-20.04) (push) Failing after 5m51s
CI/CD Pipeline / Build and Test (Release, gcc, ubuntu-latest) (push) Failing after 6m0s
CI/CD Pipeline / Docker Build Test (push) Failing after 1m0s
CI/CD Pipeline / Performance Benchmarks (push) Has been skipped
CI/CD Pipeline / Build Documentation (push) Failing after 25s
CI/CD Pipeline / Create Release Package (push) Has been skipped

This commit is contained in:
2025-06-23 12:19:22 +02:00
parent 7b27d5c1f3
commit 235367da01
2 changed files with 30 additions and 23 deletions

View File

@@ -64,19 +64,25 @@ elseif(EXISTS "${liblinear_SOURCE_DIR}/newton.cpp")
list(APPEND LIBLINEAR_SOURCES "${liblinear_SOURCE_DIR}/newton.cpp") list(APPEND LIBLINEAR_SOURCES "${liblinear_SOURCE_DIR}/newton.cpp")
endif() endif()
# Check for BLAS files in blas directory # Check for BLAS files in blas directory - Fixed to ensure they're included
file(GLOB BLAS_C_FILES "${liblinear_SOURCE_DIR}/blas/*.c") if(EXISTS "${liblinear_SOURCE_DIR}/blas")
file(GLOB BLAS_CPP_FILES "${liblinear_SOURCE_DIR}/blas/*.cpp") # Explicitly add the required BLAS source files
set(BLAS_FILES
"${liblinear_SOURCE_DIR}/blas/daxpy.c"
"${liblinear_SOURCE_DIR}/blas/ddot.c"
"${liblinear_SOURCE_DIR}/blas/dnrm2.c"
"${liblinear_SOURCE_DIR}/blas/dscal.c"
)
if(BLAS_C_FILES OR BLAS_CPP_FILES) # Check which BLAS files actually exist and add them
list(APPEND LIBLINEAR_SOURCES ${BLAS_C_FILES} ${BLAS_CPP_FILES}) foreach(blas_file ${BLAS_FILES})
else() if(EXISTS ${blas_file})
# Try alternative BLAS file names list(APPEND LIBLINEAR_SOURCES ${blas_file})
foreach(blas_file daxpy ddot dnrm2 dscal) message(STATUS "Adding BLAS file: ${blas_file}")
if(EXISTS "${liblinear_SOURCE_DIR}/blas/${blas_file}.c")
list(APPEND LIBLINEAR_SOURCES "${liblinear_SOURCE_DIR}/blas/${blas_file}.c")
endif() endif()
endforeach() endforeach()
else()
message(WARNING "BLAS directory not found in liblinear source")
endif() endif()
# Create liblinear object library if we have source files # Create liblinear object library if we have source files

View File

@@ -16,9 +16,10 @@ using namespace svm_classifier;
*/ */
std::pair<torch::Tensor, torch::Tensor> generate_multiclass_data(int n_samples = 60, std::pair<torch::Tensor, torch::Tensor> generate_multiclass_data(int n_samples = 60,
int n_features = 2, int n_features = 2,
int n_classes = 3) int n_classes = 3,
int seed = 42)
{ {
torch::manual_seed(42); torch::manual_seed(seed);
auto X = torch::randn({ n_samples, n_features }); auto X = torch::randn({ n_samples, n_features });
auto y = torch::randint(0, n_classes, { n_samples }); auto y = torch::randint(0, n_classes, { n_samples });
@@ -123,7 +124,7 @@ TEST_CASE("OneVsRestStrategy Prediction", "[unit][multiclass_strategy]")
{ {
auto predictions = strategy.predict(X_test, converter); auto predictions = strategy.predict(X_test, converter);
REQUIRE(predictions.size() == X_test.size(0)); REQUIRE(static_cast<int64_t>(predictions.size()) == X_test.size(0));
// Check that all predictions are valid class labels // Check that all predictions are valid class labels
auto classes = strategy.get_classes(); auto classes = strategy.get_classes();
@@ -136,8 +137,8 @@ TEST_CASE("OneVsRestStrategy Prediction", "[unit][multiclass_strategy]")
{ {
auto decision_values = strategy.decision_function(X_test, converter); auto decision_values = strategy.decision_function(X_test, converter);
REQUIRE(decision_values.size() == X_test.size(0)); REQUIRE(static_cast<int64_t>(decision_values.size()) == X_test.size(0));
REQUIRE(decision_values[0].size() == strategy.get_n_classes()); REQUIRE(static_cast<int>(decision_values[0].size()) == strategy.get_n_classes());
// Decision values should be real numbers // Decision values should be real numbers
for (const auto& sample_decisions : decision_values) { for (const auto& sample_decisions : decision_values) {
@@ -173,7 +174,7 @@ TEST_CASE("OneVsRestStrategy Probability Prediction", "[unit][multiclass_strateg
if (strategy.supports_probability()) { if (strategy.supports_probability()) {
auto probabilities = strategy.predict_proba(X, converter); auto probabilities = strategy.predict_proba(X, converter);
REQUIRE(probabilities.size() == X.size(0)); REQUIRE(static_cast<int64_t>(probabilities.size()) == X.size(0));
REQUIRE(probabilities[0].size() == 3); // 3 classes REQUIRE(probabilities[0].size() == 3); // 3 classes
// Check probability constraints // Check probability constraints
@@ -269,7 +270,7 @@ TEST_CASE("OneVsOneStrategy Prediction", "[unit][multiclass_strategy]")
{ {
auto predictions = strategy.predict(X_test, converter); auto predictions = strategy.predict(X_test, converter);
REQUIRE(predictions.size() == X_test.size(0)); REQUIRE(static_cast<int64_t>(predictions.size()) == X_test.size(0));
auto classes = strategy.get_classes(); auto classes = strategy.get_classes();
for (int pred : predictions) { for (int pred : predictions) {
@@ -281,7 +282,7 @@ TEST_CASE("OneVsOneStrategy Prediction", "[unit][multiclass_strategy]")
{ {
auto decision_values = strategy.decision_function(X_test, converter); auto decision_values = strategy.decision_function(X_test, converter);
REQUIRE(decision_values.size() == X_test.size(0)); REQUIRE(static_cast<int64_t>(decision_values.size()) == X_test.size(0));
// For 3 classes, OvO should have C(3,2) = 3 pairwise comparisons // For 3 classes, OvO should have C(3,2) = 3 pairwise comparisons
REQUIRE(decision_values[0].size() == 3); REQUIRE(decision_values[0].size() == 3);
@@ -298,7 +299,7 @@ TEST_CASE("OneVsOneStrategy Prediction", "[unit][multiclass_strategy]")
// OvO probability estimation is more complex // OvO probability estimation is more complex
auto probabilities = strategy.predict_proba(X_test, converter); auto probabilities = strategy.predict_proba(X_test, converter);
REQUIRE(probabilities.size() == X_test.size(0)); REQUIRE(static_cast<int64_t>(probabilities.size()) == X_test.size(0));
REQUIRE(probabilities[0].size() == 3); // 3 classes REQUIRE(probabilities[0].size() == 3); // 3 classes
// Check basic probability constraints // Check basic probability constraints
@@ -395,7 +396,7 @@ TEST_CASE("MulticlassStrategy Edge Cases", "[unit][multiclass_strategy]")
// Implementation might extend to binary case // Implementation might extend to binary case
auto predictions = strategy.predict(X, converter); auto predictions = strategy.predict(X, converter);
REQUIRE(predictions.size() == X.size(0)); REQUIRE(static_cast<int64_t>(predictions.size()) == X.size(0));
} }
SECTION("Very small dataset") SECTION("Very small dataset")
@@ -432,7 +433,7 @@ TEST_CASE("MulticlassStrategy Edge Cases", "[unit][multiclass_strategy]")
REQUIRE(strategy.get_n_classes() == 2); REQUIRE(strategy.get_n_classes() == 2);
auto predictions = strategy.predict(X, converter); auto predictions = strategy.predict(X, converter);
REQUIRE(predictions.size() == X.size(0)); REQUIRE(static_cast<int64_t>(predictions.size()) == X.size(0));
} }
} }
@@ -510,7 +511,7 @@ TEST_CASE("MulticlassStrategy Memory Management", "[unit][multiclass_strategy]")
REQUIRE(metrics.status == TrainingStatus::SUCCESS); REQUIRE(metrics.status == TrainingStatus::SUCCESS);
auto predictions = strategy.predict(X, converter); auto predictions = strategy.predict(X, converter);
REQUIRE(predictions.size() == X.size(0)); REQUIRE(static_cast<int64_t>(predictions.size()) == X.size(0));
} }
} }
} }