Program Listing for File pybind11KModel.h

Program Listing for File pybind11KModel.h#

Return to documentation for file (include/Karana/SOADyn/pybind11KModel.h)

/*
*Copyright(c)2024-2025KaranaDynamicsPtyLtd.Allrightsreserved.
*
*NOTICETOUSER:
*
*Thissourcecodeand/ordocumentation(the"LicensedMaterials")is
*theconfidentialandproprietaryinformationofKaranaDynamicsInc.
*UseoftheseLicensedMaterialsisgovernedbythetermsandconditions
*ofaseparatesoftwarelicenseagreementbetweenKaranaDynamicsandthe
*Licensee("LicenseAgreement").Unlessexpresslypermittedunderthat
*agreement,anyreproduction,modification,distribution,ordisclosure
*oftheLicensedMaterials,inwholeorinpart,toanythirdparty
*withoutthepriorwrittenconsentofKaranaDynamicsisstrictlyprohibited.
*
*THELICENSEDMATERIALSAREPROVIDED"ASIS"WITHOUTWARRANTYOFANYKIND.
*KARANADYNAMICSDISCLAIMSALLWARRANTIES,EXPRESSORIMPLIED,INCLUDING
*BUTNOTLIMITEDTOWARRANTIESOFMERCHANTABILITY,NON-INFRINGEMENT,AND
*FITNESSFORAPARTICULARPURPOSE.
*
*INNOEVENTSHALLKARANADYNAMICSBELIABLEFORANYDAMAGESWHATSOEVER,
*INCLUDINGBUTNOTLIMITEDTOLOSSOFPROFITS,DATA,ORUSE,EVENIF
*ADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGES,WHETHERINCONTRACT,TORT,
*OROTHERWISEARISINGOUTOFORINCONNECTIONWITHTHELICENSEDMATERIALS.
*
*U.S.GovernmentEndUsers:TheLicensedMaterialsarea"commercialitem"
*asdefinedat48C.F.R.2.101,andareprovidedtotheU.S.Government
*onlyasacommercialenditemunderthetermsofthislicense.
*
*AnyuseoftheLicensedMaterialsinindividualorcommercialsoftwaremust
*include,intheuserdocumentationandinternalsourcecodecomments,
*thisNotice,Disclaimer,andU.S.GovernmentUseProvision.
*/


#include"Karana/KCore/pybind11_chrono_numpy.h"
#include"Karana/SOADyn/KModel.h"
#include<pybind11/pybind11.h>
#include<pybind11/stl.h>

namespacepy=pybind11;

template<classModelClass>structPyTypeWrapper{
py::objectobj;
PyTypeWrapper(py::objecto)
:obj(std::move(o)){}
};

template<typenameT>
structhas_pybind11_caster:std::false_type{};//NOLINT(readability-identifier-naming)

template<typenameT>inlineconstexprboolhas_pybind11_caster_v=has_pybind11_caster<T>::value;

#defineADD_TO_DS_METHOD_CASTER(MODEL_CLASS,MODEL_DS_MODULE_NAME,MODEL_DS_CLASS_NAME)\
namespacepybind11::detail{\
template<>structtype_caster<PyTypeWrapper<MODEL_CLASS>>{\
usingT=PyTypeWrapper<MODEL_CLASS>;\
PYBIND11_TYPE_CASTER(T,_(#MODEL_DS_MODULE_NAME"."#MODEL_DS_CLASS_NAME));\
\
boolload(handlesrc,bool){\
value=T(py::reinterpret_borrow<py::object>(src));\
returntrue;\
}\
\
statichandlecast(constT&src,return_value_policy,handle){\
py::objectobj=src.obj;\
returnobj.release();\
}\
};\
}\
template<>structhas_pybind11_caster<PyTypeWrapper<MODEL_CLASS>>:std::true_type{};

namespaceKarana::Models{

template<classT,
classP=NoParams,
classSc=NoScratch,
classS=NoDiscreteStates,
classC=NoContinuousStates>
autoKModelPybind11(//NOLINT(readability-identifier-naming)
conststd::string&class_name,
py::module&m){
autoPyKModelClass=
py::class_<KModel<T,P,Sc,S,C>,BaseKModel,kc::ks_ptr<KModel<T, P, Sc, S, C>>>(
m,class_name.c_str())
.def("getNextModelStepTime",
&KModel<T, P, Sc, S, C>::getNextModelStepTime,
py::arg("t"),
R"raw(
Getthenextsteptimeassumingtheprovidedtime`t`isatimethemodelhasastepat.

Parameters
----------
t:Ktime
Atimethemodelhasastepat.

Returns
-------
Ktime
Thenextmodelsteptime.
)raw")

.def("getPeriod",
&KModel<T, P, Sc, S, C>::getPeriod,
R"raw(
Gettheperiodofthemodel.

Ifa`nextModelStepTime`methodexists,thisreturnsawarning.Amodelperiodand
`nextModelStepTime`cannotbothbedefinedforamodel.

Returns
-------
Ktime
Themodel'speriod.
)raw")

.def("setPeriod",
&KModel<T, P, Sc, S, C>::setPeriod,
py::arg("t"),
R"raw(
Setthemodelperiod.

Themodelperioddefinestheperiodatwhichthemodelruns.Thereareafewcasestoconsider:

1.Theperiodis0andno`nextModelStepTime`methodisdefined.Inthiscase,the
`preModelStep`/`postModelStep`methodswillruneverytimeasimulationhophappens.
2.Theperiodisnon-zero.Inthiscase,thosemethodswillrunatthespecifiedperiod.
3.Theperiodis0anda`nextModelStepTime`methodisdefined.Then,thatmethoddefineswhenthe
stepswillrun.

Amodelperiodand`nextModelStepTime`cannotbothbedefinedforamodel.Anerrorwillbe
thrownifamodelwith`nextModelStepTime`hasitsperiodset.

Parameters
----------
t:Ktime
Thenewmodelperiod.
)raw")

.def("isFinalized",
&KModel<T, P, Sc, S, C>::isFinalized,
R"raw(
Checkswhetherthemodelisfinalized.

Returns
-------
bool:
Returnsfalseiftheparamspointerisemtpyoriftheparametersarenotfinalize.Returnstrueotherwise.
)raw")

.def_readwrite("state_propagator",&KModel<T, P, Sc, S, C>::state_propagator)
.def_readwrite("debug_model",&KModel<T, P, Sc, S, C>::debug_model);

//Addparamsifaparamsclassisdefined
ifconstexpr(notstd::is_same_v<NoParams,P>){
PyKModelClass.def_readwrite("params",&KModel<T, P, Sc, S, C>::params);
}

//Addscratchifascratchclassisdefined
ifconstexpr(notstd::is_same_v<NoScratch,Sc>){
PyKModelClass.def_readwrite("scratch",&KModel<T, P, Sc, S, C>::scratch);
}

//Adddiscretestatesifadiscretestatesclassisdefined
ifconstexpr(notstd::is_same_v<NoDiscreteStates,S>){
PyKModelClass.def_readwrite("discrete_states",
&KModel<T, P, Sc, S, C>::discrete_states);
}

//Addcontinuous_statesifacontinuous_statesclassisdefined
ifconstexpr(notstd::is_same_v<NoContinuousStates,C>){
PyKModelClass.def_readwrite("continuous_states",
&KModel<T, P, Sc, S, C>::continuous_states);
}

returnPyKModelClass;
}

template<classModelClass>
voidaddToDSMethod(auto&cls,
std::string_viewmodel_class_name,
conststd::string&model_ds_module_name,
conststd::string&model_ds_class_name){

static_assert(has_pybind11_caster_v<PyTypeWrapper<ModelClass>>,
"ItlookslikeADD_TO_DS_METHOD_CASTERhasnotbeencalledforthegiven"
"modelclass.Pleasecallthismarcofirstbeforecallingthisfunction.");

cls.def(
"toDS",
[model_ds_module_name,model_ds_class_name](ModelClass&self){
autods=py::module::import(model_ds_module_name.c_str())
.attr(model_ds_class_name.c_str());
returnPyTypeWrapper<ModelClass>(ds.attr("fromModel")(self));
},
std::format(R"(Createa{}fromthis{}model.

Returns
-------
{}
A{}instancewithvaluessettomatchthismodel.
)",
model_ds_class_name,
model_class_name,
model_ds_class_name,
model_ds_class_name)
.c_str());
}

}//namespaceKarana::Models