Use ninja for the examples (#2635)

* Use ninja for the examples

Should help a little bit with doc building

* FIx some templates

* Fix template deduction error in count_x_for_y_many functions

The count_x_for_y_many and count_x_for_y_manyC functions were using
a single template parameter for both input (double) and output (size_t)
arrays, causing template deduction failures in Cython bindings.

Changed to use separate template parameters YContainer and CountContainer
to properly support different types for input y values and output counts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix types in PXD header too

* Docs should get ninja too

* Changes from clang-format

* Fix git diff argument order in clang-format script

The script was comparing PR_BRANCH to TARGET_BRANCH, which shows changes from the PR branch to the target (what's in target that's NOT in PR). For PR validation, we need the opposite: changes from target to PR (what's in PR that's NOT in target).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix Cython template deduction errors in solve_for_x_manyC and count_x_for_y_manyC

Add explicit template parameters [double, size_t] to both function calls
to resolve template type deduction errors when compiling with Cython.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix wheel building by removing return from void Cython template calls

The functions solve_for_x_manyC and count_x_for_y_manyC return void in C++.
When Cython sees a return statement with a void function call containing
template arguments with commas (e.g., [double, size_t]), it wraps the call
in the __Pyx_void_to_None macro. This macro is a simple preprocessor macro
that cannot handle the commas in template arguments, treating them as macro
argument separators instead.

The fix is to remove the return statements, making these simple void function
calls. This prevents the __Pyx_void_to_None wrapping and allows the wheel to
build successfully.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Ian Bell
2025-10-12 09:28:57 -04:00
committed by GitHub
parent 1b5ac379b5
commit d5761cb150
10 changed files with 31 additions and 27 deletions

View File

@@ -88,7 +88,7 @@ jobs:
# Build and install the wheel
pip -vv wheel .
pip install -vvv --force-reinstall --ignore-installed --upgrade --no-index `ls *.whl`
pip install pydata-sphinx-theme tqdm
pip install pydata-sphinx-theme tqdm ninja
- name: Test the installed CoolProp version
shell: bash

View File

@@ -41,7 +41,7 @@ jobs:
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
python -m pip install requests packaging
python -m pip install requests packaging ninja
- name: Figure out the TestPyPi/PyPi Version
shell: bash
@@ -64,6 +64,7 @@ jobs:
MACOSX_DEPLOYMENT_TARGET: 11.0
CIBW_ENVIRONMENT_MACOS: MACOSX_DEPLOYMENT_TARGET=11.0 SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
CIBW_BEFORE_BUILD_LINUX: >
pip install ninja &&
git config --global --add safe.directory "*"
CIBW_ENVIRONMENT_LINUX: COOLPROP_CMAKE=default,NATIVE
CIBW_BUILD: cp${{ inputs.python-version }}-*

View File

@@ -32,7 +32,7 @@ then
fi
# first find if any files changed
num=$(git diff $PR_BRANCH_NAME $TARGET_BRANCH_NAME --name-only | grep '.*\.\(cpp\|c\|hpp\|h\)$' | wc -l | tr -d '[:space:]')
num=$(git diff $TARGET_BRANCH_NAME $PR_BRANCH_NAME --name-only | grep '.*\.\(cpp\|c\|hpp\|h\)$' | wc -l | tr -d '[:space:]')
if [ $num -eq 0 ]
then
@@ -40,7 +40,7 @@ then
exit 0
fi
git diff $PR_BRANCH_NAME $TARGET_BRANCH_NAME --name-only | grep '.*\.\(cpp\|c\|hpp\|h\)$' | xargs clang-format -style=file -i -fallback-style=none
git diff $TARGET_BRANCH_NAME $PR_BRANCH_NAME --name-only | grep '.*\.\(cpp\|c\|hpp\|h\)$' | xargs clang-format -style=file -i -fallback-style=none
# clang-format will auto correct files so prepare the diff and use this as artifact
git diff > clang_format.patch

View File

@@ -20,7 +20,7 @@ FROM continuumio/miniconda3
RUN apt-get -y -m update && \
apt-get install -y \
g++ make cmake swig doxygen p7zip-full \
g++ make cmake ninja-build swig doxygen p7zip-full \
mono-mcs \
octave liboctave-dev \
r-base-dev \

View File

@@ -38,11 +38,11 @@ if __name__ == '__main__':
tee_call('python Example.py', fp, shell=True, cwd='Python')
copyfiles('Python', 'py')
if not os.path.exists('Octave'): os.mkdir('Octave')
if not os.path.exists('Octave'): os.mkdir('Octave')
O = Octave()
O.write('Octave/Example.m', O.parse())
kwargs = dict(stdout=sys.stdout, stderr=sys.stderr, shell=True, cwd='Octave')
subprocess.check_call('cmake ../../../.. -DCOOLPROP_OCTAVE_MODULE=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCOOLPROP_NO_EXAMPLES=ON', **kwargs)
subprocess.check_call('cmake ../../../.. -G Ninja -DCOOLPROP_OCTAVE_MODULE=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCOOLPROP_NO_EXAMPLES=ON', **kwargs)
subprocess.check_call('cmake --build .', **kwargs)
with codecs.open('Octave/Example.out', 'w', encoding='utf-8') as fp:
tee_call(r'octave Example.m', fp, shell=True, cwd='Octave')
@@ -52,7 +52,7 @@ if __name__ == '__main__':
J = Java()
J.write('Java/Example.java', J.parse())
kwargs = dict(stdout=sys.stdout, stderr=sys.stderr, shell=True, cwd='Java')
subprocess.check_call('cmake ../../../.. -DCOOLPROP_JAVA_MODULE=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCOOLPROP_NO_EXAMPLES=ON', **kwargs)
subprocess.check_call('cmake ../../../.. -G Ninja -DCOOLPROP_JAVA_MODULE=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCOOLPROP_NO_EXAMPLES=ON', **kwargs)
subprocess.check_call('cmake --build .', **kwargs)
subprocess.check_call(r'javac *.java', **kwargs)
with codecs.open('Java/Example.out', 'w', encoding='utf-8') as fp:
@@ -63,7 +63,7 @@ if __name__ == '__main__':
C = Csharp()
C.write('Csharp/Example.cs', C.parse())
kwargs = dict(stdout=sys.stdout, stderr=sys.stderr, shell=True, cwd='Csharp')
subprocess.check_call('cmake ../../../.. -DCOOLPROP_CSHARP_MODULE=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCOOLPROP_NO_EXAMPLES=ON', **kwargs)
subprocess.check_call('cmake ../../../.. -G Ninja -DCOOLPROP_CSHARP_MODULE=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCOOLPROP_NO_EXAMPLES=ON', **kwargs)
subprocess.check_call('cmake --build .', **kwargs)
subprocess.check_call(r'mcs -out:Example *.cs', **kwargs)
with codecs.open('Csharp/Example.out', 'w', encoding='utf-8') as fp:
@@ -74,7 +74,7 @@ if __name__ == '__main__':
RR = R()
RR.write('R/Example.R', RR.parse())
kwargs = dict(stdout=sys.stdout, stderr=sys.stderr, shell=True, cwd='R')
subprocess.check_call('cmake ../../../.. -DCOOLPROP_R_MODULE=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCOOLPROP_NO_EXAMPLES=ON -DR_BIN=/usr/bin', **kwargs)
subprocess.check_call('cmake ../../../.. -G Ninja -DCOOLPROP_R_MODULE=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCOOLPROP_NO_EXAMPLES=ON -DR_BIN=/usr/bin', **kwargs)
subprocess.check_call('cmake --build .', **kwargs)
with codecs.open('R/Example.out', 'w', encoding='utf-8') as fp:
tee_call(r'DYLD_LIBRARY_PATH=/opt/refprop Rscript Example.R', fp, shell=True, cwd='R')

View File

@@ -749,8 +749,8 @@ struct ChebyshevApproximation1D
}
/// A vectorized and templated getter (for calling from python)
template <typename Container>
const auto count_x_for_y_many(const Container& y, unsigned int bits, std::size_t max_iter, double boundsftol, Container& x) const {
template <typename YContainer, typename CountContainer>
const auto count_x_for_y_many(const YContainer& y, unsigned int bits, std::size_t max_iter, double boundsftol, CountContainer& x) const {
if (x.size() != y.size()) {
throw std::invalid_argument("x and y are not the same size");
}
@@ -760,8 +760,9 @@ struct ChebyshevApproximation1D
}
/// A vectorized and templated getter (for calling from python)
template <typename Container>
const auto count_x_for_y_manyC(const Container y[], size_t N, unsigned int bits, std::size_t max_iter, double boundsftol, Container x[]) const {
template <typename YContainer, typename CountContainer>
const auto count_x_for_y_manyC(const YContainer y[], size_t N, unsigned int bits, std::size_t max_iter, double boundsftol,
CountContainer x[]) const {
for (auto i = 0U; i < N; ++i) {
x[i] = get_x_for_y(y[i], bits, max_iter, boundsftol).size();
}

View File

@@ -61,7 +61,7 @@ class IF97BackendGenerator : public AbstractStateGenerator
{
public:
AbstractState* get_AbstractState(const std::vector<std::string>& fluid_names) {
if (fluid_names.size() == 1) { // Check that fluid_names[0] has only one component
if (fluid_names.size() == 1) { // Check that fluid_names[0] has only one component
const std::string str = fluid_names[0]; // Check that the fluid name is an alias for "Water"
if ((upper(str) == "WATER") || (upper(str) == "H2O")) {
return new IF97Backend();
@@ -708,7 +708,7 @@ double AbstractState::fundamental_derivative_of_gas_dynamics() {
// Get the derivatives of the parameters in the partial derivative with respect to T and rho
void get_dT_drho(AbstractState& AS, parameters index, CoolPropDbl& dT, CoolPropDbl& drho) {
const CoolPropDbl T = AS.T(), rho = AS.rhomolar(), rhor = AS.rhomolar_reducing(), Tr = AS.T_reducing(), dT_dtau = -pow(T, 2) / Tr,
R = AS.gas_constant(), delta = rho / rhor, tau = Tr / T;
R = AS.gas_constant(), delta = rho / rhor, tau = Tr / T;
switch (index) {
case iT:
@@ -855,7 +855,8 @@ void get_dT_drho(AbstractState& AS, parameters index, CoolPropDbl& dT, CoolPropD
const double aa = 1.0 + delta * AS.dalphar_dDelta() - delta * tau * AS.d2alphar_dDelta_dTau();
const double bb = pow(tau, 2) * (AS.d2alpha0_dTau2() + AS.d2alphar_dTau2());
const double daa_dTau = -delta * tau * AS.d3alphar_dDelta_dTau2();
const double dbb_dTau = pow(tau, 2) * (AS.d3alpha0_dTau3() + AS.d3alphar_dTau3()) + 2.0 * tau * (AS.d2alpha0_dTau2() + AS.d2alphar_dTau2());
const double dbb_dTau =
pow(tau, 2) * (AS.d3alpha0_dTau3() + AS.d3alphar_dTau3()) + 2.0 * tau * (AS.d2alpha0_dTau2() + AS.d2alphar_dTau2());
const double w = AS.speed_sound();
dT = 1.0 / 2.0 / w / T
* (pow(w, 2)
@@ -878,7 +879,7 @@ void get_dT_drho(AbstractState& AS, parameters index, CoolPropDbl& dT, CoolPropD
}
void get_dT_drho_second_derivatives(AbstractState& AS, int index, CoolPropDbl& dT2, CoolPropDbl& drho_dT, CoolPropDbl& drho2) {
const CoolPropDbl T = AS.T(), rho = AS.rhomolar(), rhor = AS.rhomolar_reducing(), Tr = AS.T_reducing(), R = AS.gas_constant(), delta = rho / rhor,
tau = Tr / T;
tau = Tr / T;
// Here we use T and rho as independent variables since derivations are already done by Thorade, 2013,
// Partial derivatives of thermodynamic state propertiesfor dynamic simulation, DOI 10.1007/s12665-013-2394-z

View File

@@ -559,7 +559,7 @@ void _PropsSImulti(const std::vector<std::string>& Outputs, const std::string& N
std::string N2 = Name2; // Make Non-constant copy of Name2 that we can modify
const bool HasPhase1 = StripPhase(N1, State); // strip phase string from first name if needed
const bool HasPhase2 = StripPhase(N2, State); // strip phase string from second name if needed
if (HasPhase1 && HasPhase2) // if both Names have a phase string, don't allow it.
if (HasPhase1 && HasPhase2) // if both Names have a phase string, don't allow it.
throw ValueError("Phase can only be specified on one of the input key strings");
try {
@@ -610,7 +610,8 @@ std::vector<std::vector<double>> PropsSImulti(const std::vector<std::string>& Ou
#endif
return std::vector<std::vector<double>>();
}
double PropsSI(const std::string& Output, const std::string& Name1, double Prop1, const std::string& Name2, double Prop2, const std::string& FluidName) {
double PropsSI(const std::string& Output, const std::string& Name1, double Prop1, const std::string& Name2, double Prop2,
const std::string& FluidName) {
#if !defined(NO_ERROR_CATCHING)
try {
#endif
@@ -642,9 +643,9 @@ double PropsSI(const std::string& Output, const std::string& Name1, double Prop1
// END OF TRY
#if !defined(NO_ERROR_CATCHING)
} catch (const std::exception& e) {
set_error_string(
e.what()
+ format(" : PropsSI(\"%s\",\"%s\",%0.10g,\"%s\",%0.10g,\"%s\")", Output.c_str(), Name1.c_str(), Prop1, Name2.c_str(), Prop2, FluidName.c_str()));
set_error_string(e.what()
+ format(" : PropsSI(\"%s\",\"%s\",%0.10g,\"%s\",%0.10g,\"%s\")", Output.c_str(), Name1.c_str(), Prop1, Name2.c_str(), Prop2,
FluidName.c_str()));
# if defined(PROPSSI_ERROR_STDOUT)
std::cout << e.what() << std::endl;
# endif

View File

@@ -145,7 +145,7 @@ cdef class ChebyshevExpansion:
def solve_for_x_many(self, double[::1] y, double a, double b, unsigned int bits, size_t max_iter, double boundstytol, double[::1] x, size_t [::1] counts):
cdef size_t N = y.shape[0]
return self.m_exp.solve_for_x_manyC(&y[0], N, a, b, bits, max_iter, boundstytol, &x[0], &counts[0])
self.m_exp.solve_for_x_manyC[double, size_t](&y[0], N, a, b, bits, max_iter, boundstytol, &x[0], &counts[0])
ctypedef supanc.ChebyshevApproximation1D[ArrayType] ChebApprox1D
from cython.operator cimport dereference as deref
@@ -179,7 +179,7 @@ cdef class ChebyshevApproximation1D:
def count_x_for_y_many(self, double[::1] y, unsigned int bits, size_t max_iter, double boundstytol, size_t[::1] counts):
assert y.shape[0] == counts.shape[0]
cdef size_t N = y.shape[0]
return self.thisptr.count_x_for_y_manyC(&y[0], N, bits, max_iter, boundstytol, &counts[0])
self.thisptr.count_x_for_y_manyC[double, size_t](&y[0], N, bits, max_iter, boundstytol, &counts[0])
def monotonic_intervals(self):
return self.thisptr.get_monotonic_intervals()

View File

@@ -27,7 +27,7 @@ cdef extern from "superancillary/superancillary.h" namespace "CoolProp::superanc
U eval[U](const U& x) const
void eval_manyC[U](const U x[], U v[], size_t) const
double solve_for_x(double, double, double, unsigned int, size_t, double) const
void solve_for_x_manyC[U](const U[], size_t, double, double, unsigned int, size_t, double, U[], U[]) const
void solve_for_x_manyC[T, CountsT](const T[], size_t, double, double, unsigned int, size_t, double, T[], CountsT[]) const
cdef cppclass ChebyshevApproximation1D[ArrayType]:
ChebyshevApproximation1D(vector[ChebyshevExpansion[ArrayType]]&&) except +ValueError
@@ -39,7 +39,7 @@ cdef extern from "superancillary/superancillary.h" namespace "CoolProp::superanc
const vector[double] m_x_at_extrema # The values of the independent variable at the extrema of the expansions
const vector[IntervalMatch] get_monotonic_intervals() # The intervals that are monotonic
vector[pair[double, int]] get_x_for_y(double, unsigned int, size_t, double) const
void count_x_for_y_manyC[U](const U[], size_t, unsigned int, size_t, double, U[]) const
void count_x_for_y_manyC[YContainer, CountContainer](const YContainer[], size_t, unsigned int, size_t, double, CountContainer[]) const
cdef cppclass SuperAncillary[ArrayType]:
SuperAncillary(const string&) except +ValueError