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
473 changes: 2 additions & 471 deletions docs/api/api_reference.json

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions docs/en/release_note/ommx-3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ Python SDK 3.0.0 contains breaking API changes. A migration guide is available i

## Unreleased

### ⚠ `to_bytes` / `from_bytes` removed from non-top-level types ([#845](https://github.com/Jij-Inc/ommx/pull/845))

Bytes serialization is removed from the following component-level types:

- {class}`~ommx.v1.Function`, {class}`~ommx.v1.Linear`, {class}`~ommx.v1.Quadratic`, {class}`~ommx.v1.Polynomial`
- {class}`~ommx.v1.Parameter`
- {class}`~ommx.v1.NamedFunction`, {class}`~ommx.v1.EvaluatedNamedFunction`, {class}`~ommx.v1.SampledNamedFunction`
- {class}`~ommx.v1.DecisionVariable`, {class}`~ommx.v1.EvaluatedDecisionVariable`, {class}`~ommx.v1.SampledDecisionVariable`

These methods originally existed to ferry values across the Python ↔ Rust boundary back when the Python SDK had its own protobuf-based wrapper layer and had to serialize on every hop. With the v3 transition to direct PyO3 re-exports the boundary disappears, so element-level bytes round-trips no longer serve a purpose, and keeping them aligned with the upcoming metadata-storage redesign would only add maintenance cost. `to_bytes` / `from_bytes` remain available on the container types ({class}`~ommx.v1.Instance`, {class}`~ommx.v1.ParametricInstance`, {class}`~ommx.v1.Solution`, {class}`~ommx.v1.SampleSet`) and on the cross-evaluate DTOs ({class}`~ommx.v1.State`, {class}`~ommx.v1.Samples`, {class}`~ommx.v1.Parameters`) — use those when you need to persist or exchange data on disk or over the wire.

### 🆕 OpenTelemetry-based tracing and profiling ([#816](https://github.com/Jij-Inc/ommx/pull/816), [#823](https://github.com/Jij-Inc/ommx/pull/823), [#826](https://github.com/Jij-Inc/ommx/pull/826), [#828](https://github.com/Jij-Inc/ommx/pull/828), [#829](https://github.com/Jij-Inc/ommx/pull/829))

The legacy `log` + `pyo3-log` → Python `logging` bridge is replaced by a `tracing` + `pyo3-tracing-opentelemetry` pipeline, so the Rust core's spans can now be consumed through the Python OTel SDK.
Expand Down
11 changes: 11 additions & 0 deletions docs/ja/release_note/ommx-3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ Python SDK 3.0.0にはAPIの破壊的な変更が含まれます。マイグレ

## Unreleased

### ⚠ 部品型から `to_bytes` / `from_bytes` を削除 ([#845](https://github.com/Jij-Inc/ommx/pull/845))

以下の部品型からバイト列シリアライズを削除しました:

- {class}`~ommx.v1.Function`, {class}`~ommx.v1.Linear`, {class}`~ommx.v1.Quadratic`, {class}`~ommx.v1.Polynomial`
- {class}`~ommx.v1.Parameter`
- {class}`~ommx.v1.NamedFunction`, {class}`~ommx.v1.EvaluatedNamedFunction`, {class}`~ommx.v1.SampledNamedFunction`
- {class}`~ommx.v1.DecisionVariable`, {class}`~ommx.v1.EvaluatedDecisionVariable`, {class}`~ommx.v1.SampledDecisionVariable`

これらのメソッドは元々、Python SDK が独自の protobuf ベースのラッパー層を持っていた時代に Python ↔ Rust 境界を跨ぐたびにシリアライズが必要だったために用意されていたものでした。v3 で全型を PyO3 から直接再エクスポートする方針に切り替わったことでこの境界自体が消え、要素単位のバイト列ラウンドトリップは役目を終えています。今後予定しているメタデータ管理方式の見直しに合わせて維持し続けるコストも見合わなくなったため、ここで廃止します。永続化やプロセス間でのデータ交換が必要な場合は、これまで通りコンテナ型({class}`~ommx.v1.Instance` / {class}`~ommx.v1.ParametricInstance` / {class}`~ommx.v1.Solution` / {class}`~ommx.v1.SampleSet`)と evaluate 用の DTO({class}`~ommx.v1.State` / {class}`~ommx.v1.Samples` / {class}`~ommx.v1.Parameters`)の `to_bytes` / `from_bytes` をご利用ください。

### 🆕 OpenTelemetryベースのトレーシング/プロファイリング ([#816](https://github.com/Jij-Inc/ommx/pull/816), [#823](https://github.com/Jij-Inc/ommx/pull/823), [#826](https://github.com/Jij-Inc/ommx/pull/826), [#828](https://github.com/Jij-Inc/ommx/pull/828), [#829](https://github.com/Jij-Inc/ommx/pull/829))

従来の `log` + `pyo3-log` 経由のPython `logging` ブリッジを廃止し、Rustコアを `tracing` + `pyo3-tracing-opentelemetry` ベースに切り替えて、Python OTel SDKを通じて可視化できるようになりました。
Expand Down
17 changes: 0 additions & 17 deletions python/ommx-tests/tests/test_named_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,6 @@ def test_optional_fields_default(self):
assert nf.parameters == {}


class TestNamedFunctionSerialization:
def test_roundtrip(self):
x = DecisionVariable.integer(1)
nf = NamedFunction(
id=7,
function=2 * x + 1,
name="test",
subscripts=[3],
)
data = nf.to_bytes()
nf2 = NamedFunction.from_bytes(data)
assert nf2.id == 7
assert nf2.name == "test"
assert nf2.subscripts == [3]
assert nf2.function.evaluate({1: 5.0}) == 11.0


class TestNamedFunctionArithmetic:
def test_add(self):
x = DecisionVariable.integer(1)
Expand Down
7 changes: 0 additions & 7 deletions python/ommx-tests/tests/test_serialize.py

This file was deleted.

33 changes: 0 additions & 33 deletions python/ommx/ommx/_ommx_rust/__init__.pyi

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 1 addition & 10 deletions python/ommx/src/decision_variable.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{Constraint, Function, Linear, Parameter, Polynomial, Quadratic, VariableBound};
use anyhow::Result;
use ommx::{v1, ATol, LinearMonomial, VariableID};
use pyo3::{prelude::*, types::PyBytes, Bound, PyAny};
use pyo3::{prelude::*, Bound, PyAny};
use std::collections::HashMap;

/// Decision variable in an optimization problem.
Expand Down Expand Up @@ -277,15 +277,6 @@ impl DecisionVariable {
)
}

#[staticmethod]
pub fn from_bytes(bytes: &Bound<PyBytes>) -> Result<Self> {
Ok(Self(ommx::DecisionVariable::from_bytes(bytes.as_bytes())?))
}

pub fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
PyBytes::new(py, &self.0.to_bytes())
}

pub fn __repr__(&self) -> String {
format!(
"DecisionVariable(id={}, kind={}, name=\"{}\", bound=[{}, {}])",
Expand Down
14 changes: 1 addition & 13 deletions python/ommx/src/evaluated_decision_variable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use anyhow::Result;
use pyo3::{prelude::*, types::PyBytes, Bound};
use pyo3::prelude::*;

#[pyo3_stub_gen::derive::gen_stub_pyclass]
#[pyclass]
Expand All @@ -8,17 +7,6 @@ pub struct EvaluatedDecisionVariable(pub ommx::EvaluatedDecisionVariable);
#[pyo3_stub_gen::derive::gen_stub_pymethods]
#[pymethods]
impl EvaluatedDecisionVariable {
#[staticmethod]
pub fn from_bytes(bytes: &Bound<PyBytes>) -> Result<Self> {
Ok(Self(ommx::EvaluatedDecisionVariable::from_bytes(
bytes.as_bytes(),
)?))
}

pub fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
PyBytes::new(py, &self.0.to_bytes())
}

/// Get the variable ID
#[getter]
pub fn id(&self) -> u64 {
Expand Down
14 changes: 1 addition & 13 deletions python/ommx/src/evaluated_named_function.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use anyhow::Result;
use pyo3::{prelude::*, types::PyBytes, Bound};
use pyo3::{prelude::*, Bound};
use std::collections::{HashMap, HashSet};

/// EvaluatedNamedFunction wrapper for Python
Expand All @@ -11,17 +10,6 @@ pub struct EvaluatedNamedFunction(pub ommx::EvaluatedNamedFunction);
#[pyo3_stub_gen::derive::gen_stub_pymethods]
#[pymethods]
impl EvaluatedNamedFunction {
#[staticmethod]
pub fn from_bytes(bytes: &Bound<PyBytes>) -> Result<Self> {
Ok(Self(ommx::EvaluatedNamedFunction::from_bytes(
bytes.as_bytes(),
)?))
}

pub fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
PyBytes::new(py, &self.0.to_bytes())
}

#[getter]
pub fn id(&self) -> u64 {
self.0.id.into_inner()
Expand Down
16 changes: 1 addition & 15 deletions python/ommx/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ use crate::{
use anyhow::{anyhow, Result};
use approx::AbsDiffEq;
use ommx::{ATol, Coefficient, CoefficientError, Evaluate, LinearMonomial};
use pyo3::{
exceptions::PyTypeError,
prelude::*,
types::{PyBytes, PyDict},
Bound, PyAny,
};
use pyo3::{exceptions::PyTypeError, prelude::*, types::PyDict, Bound, PyAny};
use std::collections::{BTreeMap, BTreeSet};

/// General mathematical function of decision variables.
Expand Down Expand Up @@ -218,15 +213,6 @@ impl Function {
Self(ommx::Function::from(polynomial.0.clone()))
}

#[staticmethod]
pub fn from_bytes(bytes: &Bound<PyBytes>) -> Result<Self> {
Ok(Self(ommx::Function::from_bytes(bytes.as_bytes())?))
}

pub fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
PyBytes::new(py, &self.0.to_bytes())
}

/// Try to convert this function to a linear function.
///
/// Returns Some(Linear) if the function can be represented as linear,
Expand Down
15 changes: 1 addition & 14 deletions python/ommx/src/linear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ use anyhow::{anyhow, Result};
use approx::AbsDiffEq;
use ommx::LinearMonomial;
use ommx::{ATol, Coefficient, CoefficientError, Evaluate};
use pyo3::{
prelude::*,
types::{PyBytes, PyDict},
Bound, PyAny,
};
use pyo3::{prelude::*, types::PyDict, Bound, PyAny};
use std::collections::BTreeMap;

/// Linear function of decision variables.
Expand Down Expand Up @@ -162,15 +158,6 @@ impl Linear {
Ok(Self(inner))
}

#[staticmethod]
pub fn from_bytes(bytes: &Bound<PyBytes>) -> Result<Self> {
Ok(Self(ommx::Linear::from_bytes(bytes.as_bytes())?))
}

pub fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
PyBytes::new(py, &self.0.to_bytes())
}

#[getter]
pub fn linear_terms(&self) -> BTreeMap<u64, f64> {
self.0
Expand Down
13 changes: 1 addition & 12 deletions python/ommx/src/named_function.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{Constraint, EvaluatedNamedFunction, Function, State};
use ommx::{Evaluate, NamedFunctionID};
use pyo3::{prelude::*, types::PyBytes, Bound, PyAny};
use pyo3::{prelude::*, Bound, PyAny};
use std::collections::HashMap;

/// NamedFunction wrapper for Python
Expand Down Expand Up @@ -77,17 +77,6 @@ impl NamedFunction {
self.0.description.clone()
}

#[staticmethod]
pub fn from_bytes(bytes: &Bound<PyBytes>) -> PyResult<Self> {
ommx::NamedFunction::from_bytes(bytes.as_bytes())
.map(Self)
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))
}

pub fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
PyBytes::new(py, &self.0.to_bytes())
}

/// Evaluate the named function with the given state.
///
/// **Args:**
Expand Down
15 changes: 2 additions & 13 deletions python/ommx/src/parameter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::{Constraint, Function, Linear, Polynomial, Quadratic};
use anyhow::Result;
use ommx::{LinearMonomial, Message, VariableID};
use pyo3::{prelude::*, types::PyBytes, Bound, PyAny};
use ommx::{LinearMonomial, VariableID};
use pyo3::{prelude::*, Bound, PyAny};
use std::collections::HashMap;

/// Parameter in an optimization problem.
Expand Down Expand Up @@ -140,16 +139,6 @@ impl Parameter {
self.0.description.clone().unwrap_or_default()
}

#[staticmethod]
pub fn from_bytes(bytes: &Bound<PyBytes>) -> Result<Self> {
let inner = ommx::v1::Parameter::decode(bytes.as_bytes())?;
Ok(Self(inner))
}

pub fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
PyBytes::new(py, &self.0.encode_to_vec())
}

pub fn __repr__(&self) -> String {
format!("Parameter(id={}, name=\"{}\")", self.id(), self.name(),)
}
Expand Down
15 changes: 1 addition & 14 deletions python/ommx/src/polynomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ use anyhow::{anyhow, Result};
use approx::AbsDiffEq;
use ommx::MonomialDyn;
use ommx::{ATol, Coefficient, CoefficientError, Evaluate, LinearMonomial};
use pyo3::{
prelude::*,
types::{PyBytes, PyDict},
Bound, PyAny,
};
use pyo3::{prelude::*, types::PyDict, Bound, PyAny};
use std::collections::BTreeMap;

/// Polynomial function of decision variables.
Expand Down Expand Up @@ -75,15 +71,6 @@ impl Polynomial {
Ok(Self(out))
}

#[staticmethod]
pub fn from_bytes(bytes: &Bound<PyBytes>) -> Result<Self> {
Ok(Self(ommx::Polynomial::from_bytes(bytes.as_bytes())?))
}

pub fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
PyBytes::new(py, &self.0.to_bytes())
}

#[pyo3(signature = (other, atol=ATol::default().into_inner()))]
pub fn almost_equal(&self, other: &Polynomial, atol: f64) -> bool {
self.0.abs_diff_eq(&other.0, ommx::ATol::new(atol).unwrap())
Expand Down
Loading
Loading