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
10 changes: 5 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ jobs:
- name: Set compile target
shell: bash
run: |
if [[ "$RUNNER_OS" == "Linux" ]]; then
VCPKG_HOST_TRIPLET=x64-linux-dynamic
elif [[ "$RUNNER_OS" == "Windows" ]]; then
VCPKG_HOST_TRIPLET=x64-mingw-dynamic
if [[ "$RUNNER_OS" == "Windows" ]]; then
VCPKG_HOST_TRIPLET=x64-windows-static-md
elif [[ "$RUNNER_OS" == "Linux" ]]; then
VCPKG_HOST_TRIPLET=x64-linux
elif [[ "$RUNNER_OS" == "macOS" ]]; then
VCPKG_HOST_TRIPLET=arm64-osx-dynamic
VCPKG_HOST_TRIPLET=arm64-osx
fi
echo VCPKG_HOST_TRIPLET="$VCPKG_HOST_TRIPLET" >> $GITHUB_ENV
echo $VCPKG_HOST_TRIPLET
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Cache dependencies
- name: Cache dependencies. # TODO - this may not work on linux b/c os is different than container?
id: cache-vcpkg-deps
uses: actions/cache@v4
with:
Expand All @@ -38,13 +38,13 @@ jobs:
run: |
case "${RUNNER_OS}" in
"Windows")
VCPKG_HOST_TRIPLET="x64-mingw-dynamic"
VCPKG_HOST_TRIPLET="x64-windows-static-md"
;;
"Linux")
VCPKG_HOST_TRIPLET="x64-linux-dynamic"
VCPKG_HOST_TRIPLET="x64-linux"
;;
"macOS")
VCPKG_HOST_TRIPLET="arm64-osx-dynamic"
VCPKG_HOST_TRIPLET="arm64-osx"
;;
*)
echo "Unsupported RUNNER_OS: ${RUNNER_OS}"
Expand Down
18 changes: 16 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 3.4...3.18)

project(cppcore)

set(VCPKG_HOST_TRIPLET $ENV{VCPKG_HOST_TRIPLET})
set(VCPKG_HOST_TRIPLET $ENV{VCPKG_HOST_TRIPLET})
Copy link

Copilot AI Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line appears to be a duplicate removal, but the same line is set again on line 5. This creates confusion about whether this is intentional duplication or an incomplete cleanup.

Suggested change
set(VCPKG_HOST_TRIPLET $ENV{VCPKG_HOST_TRIPLET})

Copilot uses AI. Check for mistakes.

set(PYBIND11_FINDPYTHON ON)
Expand All @@ -13,9 +12,24 @@ message(STATUS "vcpkg Triplet: ${VCPKG_HOST_TRIPLET}")
set(EIGEN_PATH "${CMAKE_SOURCE_DIR}/vcpkg_installed/${VCPKG_HOST_TRIPLET}/include")
message(STATUS "Eigen Path: ${EIGEN_PATH}")

set(GSL_DIR "${CMAKE_SOURCE_DIR}/vcpkg_installed/${VCPKG_HOST_TRIPLET}")
message(STATUS "GSL Path: ${GSL_DIR}")
set(GSL_INCLUDE_DIR "${GSL_DIR}/include")
set(GSL_LIBRARY_DIR "${GSL_DIR}/lib")
find_library(GSL_LIB gsl PATHS "${GSL_LIBRARY_DIR}")
find_library(GSLCBLAS_LIB gslcblas PATHS "${GSL_LIBRARY_DIR}")

set(NLOPT_DIR "${CMAKE_SOURCE_DIR}/vcpkg_installed/${VCPKG_HOST_TRIPLET}")
message(STATUS "NLOPT Path: ${NLOPT_DIR}")
set(NLOPT_DIR_INCLUDE_DIR "${NLOPT_DIR}/include")
set(NLOPT_DIR_LIBRARY_DIR "${NLOPT_DIR}/lib")
find_library(NLOPT_LIB nlopt PATHS "${NLOPT_DIR_LIBRARY_DIR}")

pybind11_add_module(cppcore src/cpp/main.cpp)

include_directories(${CMAKE_SOURCE_DIR}/src/cpp ${EIGEN_PATH})
include_directories(${CMAKE_SOURCE_DIR}/src/cpp ${EIGEN_PATH} ${GSL_INCLUDE_DIR} ${NLOPT_DIR_INCLUDE_DIR})
Copy link

Copilot AI Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using global 'include_directories' is discouraged in modern CMake. Consider using 'target_include_directories' exclusively, which you're already doing on line 31.

Suggested change
include_directories(${CMAKE_SOURCE_DIR}/src/cpp ${EIGEN_PATH} ${GSL_INCLUDE_DIR} ${NLOPT_DIR_INCLUDE_DIR})

Copilot uses AI. Check for mistakes.
target_include_directories(cppcore PRIVATE ${GSL_INCLUDE_DIR} ${NLOPT_DIR_INCLUDE_DIR})
target_link_libraries(cppcore PRIVATE ${GSL_LIB} ${GSLCBLAS_LIB} ${NLOPT_LIB})

target_compile_definitions(
cppcore
Expand Down
38 changes: 38 additions & 0 deletions src/cpp/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <gsl/gsl_sf_bessel.h>
#include <Eigen/Dense>
#include <nlopt.h>

#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
Expand Down Expand Up @@ -32,6 +35,37 @@ py::array_t<double> eigen_matmul(py::array_t<double, py::array::c_style | py::ar
);
}

// GSL test
double gsl_bessel(double x) {
return gsl_sf_bessel_J0(x);
}

// NLOPT test
double objfunc(unsigned n, const double* x, double* grad, void*) {
if (grad) {
grad[0] = 2 * (x[0] - 1);
grad[1] = 2 * (x[1] - 2);
}
return (x[0] - 1) * (x[0] - 1) + (x[1] - 2) * (x[1] - 2);
}
std::vector<double> nlopt_demo(const std::vector<double>& lower_bounds,
const std::vector<double>& upper_bounds) {
if (lower_bounds.size() != 2 || upper_bounds.size() != 2)
throw std::invalid_argument("Bounds must have size 2");

nlopt_opt opt = nlopt_create(NLOPT_LN_NELDERMEAD, 2);
nlopt_set_lower_bounds(opt, lower_bounds.data());
nlopt_set_upper_bounds(opt, upper_bounds.data());
nlopt_set_min_objective(opt, objfunc, nullptr);

double x[2] = {0.0, 0.0};
double minf;
int result = nlopt_optimize(opt, x, &minf);
nlopt_destroy(opt);
if (result < 0) throw std::runtime_error("nlopt failed");
return {x[0], x[1]};
}

PYBIND11_MODULE(cppcore, m) {
m.doc() = R"pbdoc(
Pybind11 example plugin
Expand Down Expand Up @@ -59,4 +93,8 @@ PYBIND11_MODULE(cppcore, m) {
)pbdoc");

m.def("eigen_matmul", &eigen_matmul, "Matrix multiplication using Eigen");
m.def("gsl_bessel", &gsl_bessel, "Bessel function using GSL");
m.def("nlopt_optimize", &nlopt_demo,
py::arg("lower_bounds"), py::arg("upper_bounds"),
"Run NLOPT optimization with specified bounds");
}
11 changes: 11 additions & 0 deletions tests/test_basic.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest
import numpy as np

import demo
Expand All @@ -16,3 +17,13 @@ def test_eigen_matmul():
result = cppcore.eigen_matmul(a, b)
expected = np.matmul(a, b)
np.testing.assert_allclose(result, expected)


def test_gsl_bessel():
assert pytest.approx(1.0, rel=1e-8) == cppcore.gsl_bessel(0.0)
assert pytest.approx(0.7651976865, rel=1e-8) == cppcore.gsl_bessel(1.0)


def test_nlopt_optimize():
res = cppcore.nlopt_optimize([-10, -10], [10, 10])
assert pytest.approx([1.0, 2.0]) == res