Python SDK v2 から v3 へのマイグレーションガイド#
警告
この v2 から v3 へのマイグレーションガイドはまだ準備中です。英語版も現時点では未完成であり、Python SDK v3 の API 変更作業も進行中です。英語版が完成したら、この日本語版もそれに合わせて同期します。それまでは、このページを確定版の移行手順ではなく mock として扱ってください。
この節の基準バージョンは v2.5.1(tag python-2.5.1)です。それ以前の 2.x から移行する場合は、v1 から v2 へのマイグレーションガイド も確認してください。
概要#
v3 では、v2 で始まった PyO3 移行が完了しました。SDK の domain class は top-level ommx から import し、内部 extension ommx._ommx_rust から re-export される Rust 実装の型になっています。ommx.v1 は Python SDK の object namespace ではなく、protobuf の wire-format schema/package 名や media type などを指す名前として扱います。
移行で特に注意する点は次の通りです。
ommx.v1.*_pb2は削除されました。SDK domain class は top-levelommxから import します。Constraintはidを持たなくなりました。制約IDはInstance.from_components(..., constraints={id: constraint})に渡すdictの key が所有します。Instance/ParametricInstance/Solutionの制約コレクションはlist[T]ではなくdict[int, T]です。decision_variablesはlistのままです。.raw、.from_raw()、.from_protobuf()、.to_protobuf()など、protobuf 層を露出する bridge API は削除されました。*_dfaccessor は property ではなく method です。instance.constraints_df()のように呼び出してください。instance.constraints[id]やinstance.decision_variablesは、snapshot ではなく書き込みが host に反映されるAttachedXhandle を返します。
1. import の変更#
1.1 protobuf submodule は削除#
ommx.v1.*_pb2 module と ommx.v1.annotation は削除されました。SDK class は top-level ommx から import します。
# v2.5.1
from ommx.v1.constraint_pb2 import Constraint, Equality
from ommx.v1.function_pb2 import Function
from ommx.v1.linear_pb2 import Linear
from ommx.v1.solution_pb2 import State
# v3
from ommx import Constraint, Equality, Function, Linear, Sense, State
.from_protobuf() / .to_protobuf() は、protobuf object と一緒に削除されています。Instance / Solution / SampleSet など全体をシリアライズする場合は、protobuf version を名前に含む bytes API を使います。新しく byte 列を作る場合は to_v2_bytes() / from_v2_bytes(...) を使い、legacy な v1 payload との互換が必要な場合だけ to_v1_bytes() / from_v1_bytes(...) を使ってください。
1.2 constraint hint helper は first-class constraint type へ#
ConstraintHints、OneHot、Sos1、Parameters wrapper は export されなくなりました。
legacy v1 の ConstraintHints は、v3 で読み込む際も advisory metadata として扱われます。Instance.from_v1_bytes(...) と ParametricInstance.from_v1_bytes(...) は hint を無視して通常制約を保持し、first-class 特殊制約へ自動昇格しません。特殊制約として扱う必要がある場合は、無視された hint だけを根拠にせず、信頼できる modeling input から対応する first-class constraint を構築してください。
# v2.5.1
from ommx.v1 import OneHot, Sos1, ConstraintHints, Parameters
# v3
from ommx import OneHotConstraint, Sos1Constraint, IndicatorConstraint
# Parameters wrapper の代わりに plain dict を渡します
parametric_instance.with_parameters({parameter_id: 1.0})
2. .raw と bridge method の削除#
v3 の各型は直接 Rust 実装を持つため、別の underlying object はありません。.raw、from_raw、from_protobuf、to_protobuf を使っていた箇所は、公開 property / method に置き換えます。
# v2.5.1
linear.raw.linear_terms
instance.raw.sense
solution.raw.optimality = Optimality.Optimal
Constraint.from_protobuf(pb_constraint)
dv.to_protobuf()
# v3
linear.linear_terms
instance.sense
solution.optimality = Optimality.Optimal
instance.to_v2_bytes()
Constraint や Function などの要素単体は、ID や host context を持てないため、原則として単体で bytes round-trip しません。Instance / Solution / SampleSet のような所有者単位でシリアライズしてください。
3. 制約IDは Constraint ではなく host 側が所有#
3.1 id / set_id() / id= は削除#
Constraint、IndicatorConstraint、OneHotConstraint、Sos1Constraint、RemovedConstraint、EvaluatedConstraint、SampledConstraint は、オブジェクト自身に ID を持ちません。ID は Instance.from_components に渡す辞書の key で決まります。
# v2.5.1
c = Constraint(
function=x + y,
equality=Constraint.EQUAL_TO_ZERO,
id=5,
name="cap",
)
c.set_id(6)
# v3
c = Constraint(function=x + y, equality=Equality.EqualToZero, name="cap")
instance = Instance.from_components(
sense=Sense.Minimize,
objective=objective,
decision_variables=decision_variables,
constraints={5: c},
)
OneHotConstraint.variables と Sos1Constraint.variables は VariableIDLike、すなわち変数 ID、detached な DecisionVariable、または AttachedDecisionVariable を受け取ります。ここでは変数の identity だけが使われます。参照する変数は引き続き host の decision_variables に含まれている必要があります。
xs = [DecisionVariable.binary(i) for i in range(3)]
oh = OneHotConstraint(variables=xs)
s1 = Sos1Constraint(variables=xs[:2])
3.2 比較演算子は detached な Constraint を返す#
==、<=、>= は引き続き Constraint を作りますが、その時点では ID を持ちません。
# v2.5.1
c = (x + y <= 5).set_id(0)
Instance.from_components(..., constraints=[c], ...)
# v3
c = x + y <= 5
Instance.from_components(..., constraints={0: c}, ...)
3.3 グローバルIDカウンタは削除#
next_constraint_id()、set_constraint_id_counter(...)、get_constraint_id_counter() などの module-level helper は削除されました。新しい制約IDが必要な場合は、所有者である Instance の instance.next_constraint_id() を使います。
4. container type の変更#
4.1 Instance.from_components(constraints=...) は dict[int, Constraint]#
制約系の引数はすべて ID を key にした dict です。decision_variables は Sequence[DecisionVariable] のままです。
# v2.5.1
Instance.from_components(
sense=Instance.MINIMIZE,
objective=obj,
decision_variables=[x0, x1],
constraints=[c0, c1],
constraint_hints=ConstraintHints(...),
)
# v3
Instance.from_components(
sense=Sense.Minimize,
objective=obj,
decision_variables=[x0, x1],
constraints={0: c0, 1: c1},
indicator_constraints={10: ic},
one_hot_constraints={20: oh},
sos1_constraints={30: sc},
)
ParametricInstance.from_components も同じ shape を取ります。
4.2 Instance / ParametricInstance / Solution の制約 accessor は dict を返す#
# v2.5.1
for c in instance.constraints:
print(c.id, c.function)
# v3
for cid, c in instance.constraints.items():
print(cid, c.function)
Instance / ParametricInstance の制約 dict は、v3 final では AttachedX handle を返します。Solution.constraints は評価結果の snapshot なので EvaluatedConstraint のままです。SampleSet.constraints / .decision_variables / .named_functions は list のままです。
5. rename、signature、挙動の変更#
主な rename / signature 変更は次の通りです。
v2.5.1 |
v3 |
|---|---|
|
|
|
|
|
|
|
|
|
plain |
|
|
# v2.5.1
instance.write_mps("out.mps.gz")
p = Parameter.new(id=3, name="w")
pi.with_parameters(Parameters(entries={p.id: 1.0}))
# v3
instance.save_mps("out.mps.gz")
p = Parameter(3, name="w")
pi.with_parameters({p.id: 1.0})
5.6 to_qubo() / to_hubo()は入力objectiveを評価結果に保持 (3.0.0, #1167)#
Driver methodは引き続き利用でき、入力をin-placeに変更します。v3では変更後の
InstanceがQUBO/HUBO solverへ渡すminimization energyをactive objectiveとして保持し、
evaluate()とevaluate_samples()は変換前のinstanceが公開していたobjective semanticsを
保持します。Python SDK v2はactive senseを戻したうえで最終的なpenalty energyを評価しており、
solver inputとuser-facing outputを混在させていました。
したがってInstance.objectiveはsolver energyを、SolutionとSampleSetは保持された入力
objectiveを表します。実行可能な事後条件はto_qubo()、
to_hubo()、evaluate()、
evaluate_samples()に記載されています。
明示的なoutput objectiveを持つInstanceまたはParametricInstanceは、v1 wire formatで
losslessに表現できません。この場合to_v1_bytes()はRuntimeErrorを送出するため、
to_v2_bytes()を使用してください。
同じpipelineはprepare()と
as_qubo_format()または
as_hubo_format()で明示的に実行できます。対応するtarget classと
編集可能なpolicyはqubo()、
hubo()、for_qubo()、
for_hubo()が提供します。
5.7 Adapterのsolve() / sample()が入力を自動的にPrepare (3.0.0, #1166)#
通常は元のInstanceをそのままsolve()またはsample()へ渡します。AdapterはそのInstanceを
変更せずに推奨Preparationを適用します。
from ommx_highs_adapter import OMMXHighsAdapter
solution = OMMXHighsAdapter.solve(instance)
application固有のPreparation Policyが必要な場合は、Instanceをin-placeでPrepareしてから preparation-free APIを使います。
policy = OMMXHighsAdapter.recommended_preparation_policy()
# 必要に応じてpolicyを調整する。
instance.prepare(OMMXHighsAdapter.INPUT_CLASS, policy)
solution = OMMXHighsAdapter.solve_without_preparation(instance)
独自Adapterでは、solve_without_preparation()またはsample_without_preparation()を実装します。
追加optionは、それを公開する各APIで明示的な型付きsignatureとして宣言し、包括的な
**kwargsは使いません。Preparationをまたいでも
意味が変わらないoptionはeasy methodから転送できます。exactなprepared inputに
意味が依存し、Preparation過程をまたぐtransportを定義しない場合、具体的なAdapterはそのoptionを
preparation-free methodだけに公開できます。Adapter inputに
output_objectiveがある場合、HiGHSとPython-MIPはdual valueを付与しません。
5.8 制約の違反量 (#1213)#
solution.total_violation_l1() は total_violation() に改名し、
total_violation_l2() は削除しました。各制約に定義した非負のスカラー値を足し合わせ、
removed 制約とすべての特殊制約を含めます。通常の等式・不等式の違反量の定義は変わりません。
solution.total_violation()
solution.constraint_violation(30, kind="one_hot")
solution.constraints_df(kind="sos1")[["feasible", "violation"]]
Indicator は有効時の内部制約の違反量、無効時は 0 です。OneHot は一つを 1、残りを 0 にする 絶対変更量の最小値、SOS1 は非ゼロを高々一つにする絶対変更量の最小値です。 Big-M lowering に依存する定義ではありません。
すべての制約を violation <= atol のときに feasible と判定します。OneHot と SOS1 では、
許容誤差を各メンバーに個別に適用する方式から、絶対変更量の合計に適用する方式へ変わります。
例えば SOS1 の値 (1, 0.00006, 0.00006) は違反量が 0.00012 なので、
atol=0.0001 では infeasible です。各小成分が個別にゼロの許容誤差内であることでは
判定しません。
変数の bounds・kind の判定は別です。離散値の丸めは制約評価より前に行われ、違反量には
その後の値を使います。解の制約充足は各制約がそれぞれの閾値を満たすことで判定し、
total_violation <= atol で判定するわけではありません。
SampleSet の feasibility と最良実行可能解の選択も、保存された許容誤差で変数の
bounds・kind を確認し、取り出した Solution の判定と一致します。そのため、
total_violation() がゼロでも変数が定義域を外れていれば infeasible になります。
制約単体の判定では、許容誤差を明示的に渡します。evaluated.feasible は
evaluated.is_feasible(atol=...) に、sampled.feasible は
sampled.feasible(atol=...)(sample ID から bool への map)に置き換えてください。
Solution/SampleSet の feasibility プロパティは引き続き利用できます。
feasibility_atol プロパティから、取り出した制約にも同じ判定条件を渡せます。
evaluated = solution.constraints[1]
evaluated.is_feasible(atol=solution.feasibility_atol)
evaluated.is_feasible(atol=1e-8) # 保存済みの同じ違反量に対する別の問い合わせ
問い合わせの許容誤差を変えても、入力の丸めや活性判定はやり直しません。 許容誤差に依存する判断結果を保持する場合に、その判断条件も保持します。 通常制約の評価値は許容誤差を保持せず、特殊制約の活性判定には使用した条件を残します。 許容誤差の役割分離と評価コンテキストの保存形式は Issue #1180 で扱います。
v2 protobuf 形式は feasible のフラグ・map と、Solution/SampleSet の
feasibility_atol を引き続き保存します。OMMX SDK がなくても判定結果とその許容誤差を
読み取れます。protobuf スキーマは変更しません。SDK は読み込み時に、保存された変数値から
OneHot/SOS1 の違反量を再計算し、保存された許容誤差を使ってフラグの整合性を検証します。
旧 v1 形式には許容誤差とネイティブの特殊制約を保存できません。
to_v1_bytes() は、保存される通常制約と変数値から SDK の既定の許容誤差で
feasibility を再計算します。from_v1_bytes() も同じ条件を使うため、v1 の書き出しと
読み込みには同じ既定の許容誤差を使用してください。この変換で feasibility が変わる
場合があります。元の許容誤差と特殊制約を保存するには v2 を使用してください。
部分評価では、active に残る特殊制約から近似ゼロのメンバーを取り除くことで、誤差の合計に 基づく feasibility が変わりうる場合、その固定を拒否します。 正確にゼロのメンバーの除去は引き続き可能です。 この場合は完全な状態を評価するか、特殊制約を lowering してから部分評価してください。 lowering 後の違反量は、以下のとおり別の尺度になります。
lowering 前後で総和の一致は保証しません。元の removed 制約と
生成した制約が残っていれば、それぞれを集計します。数式は
total_violation() を参照してください。
6. return type の変更#
Constraint.name / Constraint.description などは、未設定時に空文字列ではなく None を返します。
name = constraint.name
if name is not None:
print(name)
Linear.terms / Quadratic.terms / Polynomial.terms は property ではなく method です。
linear.terms()
quadratic.terms()
polynomial.terms()
v3 alpha の初期移行では、DecisionVariable の constructor と kind property が
protobuf の整数表現を誤って公開していました。現在の v3 API は、detached、attached、
evaluated、sampled の各 decision variable で top-level の Kind enum を一貫して
受け取り、返します。新しいコードでは Kind.Binary、Kind.Integer などを使います。
DecisionVariable.BINARY / INTEGER / … は、同じ enum 値を返す型付き互換 alias として
残します。
同じ互換方針を Constraint.EQUAL_TO_ZERO / LESS_THAN_OR_EQUAL_TO_ZERO と
Instance.MINIMIZE / MAXIMIZE にも適用します。これらは型付き alias として残しますが、
新しいコードでは Equality.* と Sense.* を使います。
from ommx import Bound, DecisionVariable, Kind
variable = DecisionVariable(0, Kind.Binary, Bound(0, 1))
assert variable.kind == Kind.Binary
assert DecisionVariable.BINARY == Kind.Binary
各 enum は protobuf の整数値との比較・hash の互換性を維持します。通常の SDK constructor と property は enum 型を使います。
assert Kind.Binary == 1
assert hash(Kind.Binary) == hash(1)
SampleSet.sample_ids は list property ではなく set を返す method になりました。list が必要な場合は sample_ids_list を使います。
ids: set[int] = sample_set.sample_ids()
ids_list: list[int] = sample_set.sample_ids_list
evaluate は、必要な decision variable ID が state にない場合や atol が不正な場合に、RuntimeError ではなく ValueError を投げます。partial_evaluate は不足 ID を許容しますが、与えた entry が不正な場合、atol が不正な場合、または dependent variable の assertion が不整合・検証不能な場合は ValueError を投げます。
v2.5.1 の Function は常に polynomial だったため、degree() と
num_terms() は常に int を返していました。v3 の Function は絶対値、
点ごとの最小値・最大値、除算、符号付き整数べきなどの複合 scalar expression も
表現できます。この表現では、両メソッドは None を返します。また、polynomial の
係数 property(terms、linear_terms、quadratic_terms、constant_term)と
content_factor() は TypeError を送出します。
# v2.5.1
degree: int = function.degree()
terms = function.terms
# v3
degree: int | None = function.degree()
if degree is None:
# 係数 map として扱わず、複合式のまま評価する
value = function.evaluate(state, atol=1e-6)
else:
terms = function.terms
非負の整数べきを展開済み polynomial のまま保持したい場合は、明示的な乗算を
使ってください。function.powi(n) と function**n は、n >= 0 の場合も意図的に
複合 power expression を構築します。
7. 削除された helper#
次の helper は削除または置き換えられました。
Linear.from_object(x)-Linear.single_term(...)、Linear.constant(...)、または arithmetic operator を使います。Linear.equals_to(other)-linear.almost_equal(other, atol=...)を使います。instance.constraint_hints-one_hot_constraints/sos1_constraints/indicator_constraintsに分かれました。ArtifactArchive/ArtifactDir系 -Artifact/ArtifactDraftに統合されました。ommx_openjij_adapter.response_to_samples(response)-decode_to_samples(response)を使用します(3.0.0: #1087)。ommx_openjij_adapter.sample_qubo_sa(...)-OMMXOpenJijSAAdapter.sample(instance)を使います。置き換え後はinstanceを変更せず、 rawSamplesではなく評価済みのSampleSetを返します (3.0.0: #1087)。
v2のOpenJij Adapterでは、constructor、sample()、solve() が
uniform_penalty_weight、penalty_weights、
inequality_integer_slack_max_rangeを直接受け取っていました。v3ではこれらの選択を推奨
PreparationPolicyへ移します。
uniform_penalty_weightとpenalty_weightsはpolicy.fixed_penaltyへ移す。inequality_integer_slack_max_rangeはpolicy.integer_slackへ移す。
constructorを直接使う場合は自動的にPrepareされないため、あらかじめ
OMMXOpenJijSAAdapter.INPUT_CLASS向けにPrepareしたInstanceを渡します。
OpenJijのinitial_stateは、このexactなprepared inputのsolver変数表現に対して定義され、dictの
keyはその変数IDです。そのためv3ではeasy methodではなく、exact-input constructor、
sample_without_preparation()、solve_without_preparation()で受け取ります。
通常のsample() / solve() workflowは§5.7で説明しています。固定penaltyが必要なmodelでは、
applicationがそのmagnitudeを選ぶ必要があります。v3はv2の暗黙なuniform weight 1.0を
使用しません。customizeしたPolicyをInstanceへ適用し、preparation-free methodを呼びます。
from ommx import FixedPenaltyPreparation
from ommx_openjij_adapter import OMMXOpenJijSAAdapter
policy = OMMXOpenJijSAAdapter.recommended_preparation_policy()
policy.fixed_penalty = (
FixedPenaltyPreparation.uniform_penalty_method_with_fixed_weight(weight=20.0)
)
source.prepare(OMMXOpenJijSAAdapter.INPUT_CLASS, policy)
samples = OMMXOpenJijSAAdapter.sample_without_preparation(source)
prepare()はsourceをin-placeで変更します。返されるSampleSetのobjectiveとsenseは
Preparation前にsourceが公開していたものです(§5.6)。Policyの詳細とpenaltyの選び方は
OpenJij tutorialを参照してください。
8. DataFrame accessor#
*_df は property ではなく method です。
# v2.5.1
df = instance.constraints_df
# v3
df = instance.constraints_df()
kind 別や removed / active 別の DataFrame accessor は、constraints_df(kind=..., removed=...) に統合されています。
instance.constraints_df(kind="normal")
instance.constraints_df(kind="one_hot")
instance.constraints_df(kind="sos1", removed=True)
solution.constraints_df(kind="indicator")
9. metadata と annotation#
Instance / Solution / SampleSet は Python dataclass ではありません。metadata は dedicated property や method で扱います。
instance.title = "portfolio"
instance.add_user_annotation("owner", "analytics")
instance.replace_annotations({"team": "optimization"})
annotations property は read-only projection です。直接 obj.annotations[...] = ... のようには変更できません。
10. AttachedX handle と snapshot#
instance.constraints[id] や instance.decision_variables は、host に書き戻す AttachedX handle を返します。
c = instance.constraints[5]
c.set_name("balance")
assert instance.constraints[5].name == "balance"
detached snapshot が必要な場合は detach() を使います。
snapshot = instance.constraints[5].detach()
10.1 fixed decision-variable values#
detached な DecisionVariable は変数定義と label の snapshot であり、固定値は持ちません。partial_evaluate(...) や legacy protobuf の substituted_value 由来の固定値は、所有者である Instance / ParametricInstance に保存されます。
fixed = instance.fixed_decision_variables()
attached = instance.attached_decision_variable(1)
assert attached.substituted_value == fixed.get(1)
df = instance.decision_variables_df()
print(df["substituted_value"])
10.2 decision_variable_analysis() の置き換え#
古い analysis object shape は公開されません。必要な role / role 由来の集合を、所有者である Instance から直接取得してください。
roles = instance.decision_variable_roles()
role = instance.decision_variable_role(1)
fixed = instance.fixed_decision_variables()
dependent = instance.dependent_decision_variable_ids()
irrelevant = instance.irrelevant_decision_variable_ids()
df = instance.decision_variables_df()
print(df["state_role"])
Adapter が solver input の変数だけを必要とする場合は instance.used_decision_variables を使います。fixed / dependent / irrelevant の分類を見ていた移行コードは、上の role helper に置き換えてください。
11. named function ID#
Named function 系も table-owned ID model に移行しています。NamedFunction、EvaluatedNamedFunction、SampledNamedFunction の row object 自身ではなく、host 側の table key が ID の source of truth です。
Python API ではユーザーが移行しやすいように .id を参照できる箇所がありますが、実装上の所有者は host table です。新しいコードでは、collection を走査するときに key と value を分けて扱うことを優先してください。
12. 要素単体の bytes round-trip#
Function / Linear / Quadratic / Polynomial / Parameter / NamedFunction family / DecisionVariable family の要素単体 to_bytes() / from_bytes() は削除されています。
要素を永続化したい場合は、所有者である Instance / Solution / SampleSet へ入れてから全体を round-trip してください。新しく byte 列を作る場合は v2 bytes API を既定にします。v1 は既存の v1 consumer / file と互換を保つ必要がある場合にだけ使ってください。
top-level root についても、protobuf version を名前に含まない Instance.to_bytes() / Instance.from_bytes(...)(および ParametricInstance、Solution、SampleSet の同名 API)は削除されています。通常は to_v2_bytes() / from_v2_bytes(...) に置き換え、legacy な v1 wire format が明示的に必要な場合だけ to_v1_bytes() / from_v1_bytes(...) を使ってください。
instance_blob = instance.to_v2_bytes()
restored = Instance.from_v2_bytes(instance_blob)
13. Artifact API: archive becomes an exchange format#
v3 では Artifact API が SQLite Local Registry を中心に整理され、.ommx file は registry から明示的に export / import する exchange format になりました。
13.1 ArtifactBuilder.new_archive / new_archive_unnamed は削除#
.ommx file を作る処理は、ArtifactDraft を commit した後の Artifact.save(path) に分離されました。
# v2
builder = ArtifactBuilder.new_archive("my_instance.ommx", "ghcr.io/jij-inc/ommx/demo:v1")
builder.add_instance(instance)
artifact = builder.build()
# v3
draft = ArtifactDraft.new("ghcr.io/jij-inc/ommx/demo:v1")
draft.add_instance(instance)
artifact = draft.commit()
artifact.save("my_instance.ommx")
13.2 anonymous archive は new_anonymous#
new_archive_unnamed(path) は ArtifactDraft.new_anonymous() に置き換わりました。v3 の anonymous Artifact も Local Registry 内では image name を持つため、artifact.image_name is None を前提にしたコードは見直してください。
draft = ArtifactDraft.new_anonymous()
draft.add_instance(instance)
artifact = draft.commit()
artifact.save("my_instance.ommx")
anonymous Artifact を多用する workflow では、定期的に ommx artifact prune-anonymous を実行してください。
13.3 Artifact.load_archive は import_archive / inspect_archive に分割#
v2 の Artifact.load_archive(file) は、v3 では目的別に分かれました。
Artifact.import_archive(file)- archive を Local Registry に import し、全 layer を読めるArtifacthandle を返します。Artifact.inspect_archive(file)- registry に書き込まず、manifest / layer descriptor だけを読む read-only path です。
# archive を使う
artifact = Artifact.import_archive("my_instance.ommx")
# 中身を確認するだけ
manifest = Artifact.inspect_archive("my_instance.ommx")
13.4 CLI flow#
archive file を直接 push する flow は廃止されました。いったん load / import して Local Registry に入れてから、image name で push します。
ommx load my_instance.ommx
ommx push ghcr.io/jij-inc/ommx/demo:v1
13.5 Artifact migration checklist#
[ ]
ArtifactBuilder.new_archive(path, image_name).build()をArtifactDraft.new(image_name).commit()+artifact.save(path)に置き換える。[ ]
ArtifactBuilder.new_archive_unnamed(path).build()をArtifactDraft.new_anonymous().commit()+artifact.save(path)に置き換える。[ ]
Artifact.load_archive(file)を、用途に応じてArtifact.import_archive(file)またはArtifact.inspect_archive(file)に置き換える。[ ]
ommx push <archive-file>をommx load <file>+ommx push <image_name>に置き換える。[ ] anonymous Artifact を大量に作る場合は
ommx artifact prune-anonymousを運用に入れる。
v2 から v3 へのチェックリスト#
[ ]
ommx.v1.*_pb2import と SDK domain class のommx.v1import を、top-levelommxからの import に置き換える。[ ]
.raw/from_raw/from_protobuf/to_protobufを削除する。新しく byte 列を作る場合は top-level root のto_v2_bytes()/from_v2_bytes(...)を使い、legacy v1 互換が必要な場合だけto_v1_bytes()/from_v1_bytes(...)を使う。[ ]
Constraint.id/set_id()/id=を削除し、host dict の key で ID を渡す。[ ]
constraints=[...]をconstraints={id: constraint}に置き換える。[ ]
constraint_hintsをone_hot_constraints/sos1_constraints/indicator_constraintsに置き換える。[ ] Adapterの推奨Preparationを使う場合は
solve()/sample()を直接呼ぶ。Policyをcustomizeする場合はInstance.prepare()後にsolve_without_preparation()/sample_without_preparation()を呼ぶ。独自Adapterにはpreparation-free methodを追加し、Adapter固有optionは公開するAPIごとに明示的な型付きsignatureとして宣言して、包括的な**kwargsは使わない。exactなprepared inputに依存するoptionのtransportを定義しない場合は、preparation-free methodだけに公開できる。[ ]
*_dfaccessor に()を付ける。[ ]
RuntimeErrorを捕捉していたevaluate/partial_evaluate周辺をValueErrorに変える。[ ]
Function.degree()/num_terms()の型注釈をNoneも受け取る形に変更し、複合式の可能性がある場合は polynomial 係数 property への access を分岐する。[ ]
decision_variable_analysis()をdecision_variable_roles()/decision_variable_role(id)/fixed_decision_variables()/dependent_decision_variable_ids()/irrelevant_decision_variable_ids()/decision_variables_df()["state_role"]に置き換える。[ ] element-level
to_bytes()/from_bytes()を、所有者全体の round-trip に置き換える。新規 payload はto_v2_bytes()、legacy v1 互換または evaluate 用 DTO ではto_v1_bytes()を使う。[ ] Artifact archive API を
ArtifactDraft/Artifact.save/Artifact.import_archive/Artifact.inspect_archiveに移行する。