surrogates_interface 4.1.0__tar.gz → 4.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: surrogates_interface
3
- Version: 4.1.0
3
+ Version: 4.1.1
4
4
  Summary: Interface for surrogate models.
5
5
  Home-page: https://gitlab.windenergy.dtu.dk/surrogate-models/surrogate-models-interface
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "surrogates_interface"
3
- version = "4.1.0"
3
+ version = "4.1.1"
4
4
  description = "Interface for surrogate models."
5
5
  authors = ["DTU Wind and Energy Systems"]
6
6
  maintainers = [
@@ -1030,48 +1030,51 @@ class SurrogateModelFamily:
1030
1030
 
1031
1031
 
1032
1032
  class PyTorchModel(SurrogateModel):
1033
- import torch
1034
- import torch._dynamo # fmt: skip
1035
- torch._dynamo.config.suppress_errors = True
1036
- import torch.func as torch_func # fmt: skip
1033
+ """
1034
+ Class that stores and evaluates an existing PyTorch model.
1035
+ """
1037
1036
 
1038
- # from torch.func import jacfwd, jacrev, jvp, vjp, vmap # fmt: skip
1037
+ def __init__(self, *args, dtype=None, max_batch=50_000, **kwargs):
1038
+ import torch
1039
+ import torch._dynamo
1039
1040
 
1040
- def __init__(self, *args, dtype=torch.float16, max_batch=50_000, **kwargs):
1041
+ torch._dynamo.config.suppress_errors = True
1041
1042
  super().__init__(*args, **kwargs)
1042
1043
  self.model.eval()
1043
- self.device = self.torch.device(
1044
- "cuda" if self.torch.cuda.is_available() else "cpu"
1045
- )
1044
+ self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
1046
1045
  self.model.to(self.device)
1047
- self.dtype = dtype
1048
- self.model.to(dtype)
1046
+ self.dtype = torch.float16 if dtype is None else dtype
1047
+ self.model.to(self.dtype)
1049
1048
  self.max_batch = max_batch
1050
1049
 
1051
1050
  def __to_numpy(self, _x):
1051
+ import torch
1052
+
1052
1053
  try:
1053
1054
  import cupy as cp
1054
1055
  except ImportError: # pragma: no cover
1055
1056
  cp = np
1056
- lalib = (
1057
- cp if self.device == self.torch.device("cuda") else np
1058
- ) # pragma: no cover
1057
+ lalib = cp if self.device == torch.device("cuda") else np # pragma: no cover
1059
1058
  return lalib.asarray(_x).astype(lalib.float32)
1060
1059
 
1061
1060
  def __to_tensor(self, _x):
1061
+ import torch
1062
+
1062
1063
  if len(_x.shape) < 2:
1063
1064
  _x = _x.reshape(1, -1)
1064
- return self.torch.as_tensor(_x, device=self.device, dtype=self.dtype)
1065
+ return torch.as_tensor(_x, device=self.device, dtype=self.dtype)
1065
1066
 
1066
1067
  def __record_in_dtype(self, _x): # pragma: no cover
1067
1068
  # TODO: could be used to retain the input/output dtype the same
1068
1069
  self.in_dtype = _x.dtype
1069
1070
 
1070
1071
  def _predict_model_output(self, x):
1072
+ import torch
1073
+
1071
1074
  x = self.__to_tensor(x)
1072
1075
 
1073
- with self.torch.no_grad():
1074
- output = self.torch.zeros(
1076
+ with torch.no_grad():
1077
+ output = torch.zeros(
1075
1078
  (x.shape[0], self.n_outputs),
1076
1079
  device=self.device,
1077
1080
  dtype=self.dtype,
@@ -1100,21 +1103,28 @@ class PyTorchModel(SurrogateModel):
1100
1103
  return self.__to_numpy(y)
1101
1104
 
1102
1105
  def _save_model(self, filepath):
1103
- self.torch.save(self.model.state_dict(), filepath)
1106
+ import torch
1107
+
1108
+ torch.save(self.model.state_dict(), filepath)
1104
1109
 
1105
1110
  @staticmethod
1106
1111
  def _load_model(filepath, model_cls):
1107
- import torch # fmt: skip
1112
+ import torch
1113
+
1108
1114
  model_cls.load_state_dict(torch.load(filepath, weights_only=True))
1109
1115
  return model_cls
1110
1116
 
1111
1117
  def _predict_model_jvp(self, x, dx):
1118
+ import torch.func as torch_func
1119
+
1112
1120
  if not hasattr(self, "batched_jvp_func"):
1113
1121
  def g(_x): # fmt: skip
1114
1122
  return self.model(_x)
1115
- def single_jvp(_x, _v): # fmt: skip
1116
- return self.torch_func.jvp(g, (_x,), (_v,))
1117
- self.batched_jvp_func = self.torch_func.vmap(single_jvp)
1123
+
1124
+ def single_jvp(_x, _v):
1125
+ return torch_func.jvp(g, (_x,), (_v,))
1126
+
1127
+ self.batched_jvp_func = torch_func.vmap(single_jvp)
1118
1128
 
1119
1129
  x = self.__to_tensor(x)
1120
1130
  dx = self.__to_tensor(dx)
@@ -1122,13 +1132,17 @@ class PyTorchModel(SurrogateModel):
1122
1132
  return self.__to_numpy(output.detach()), self.__to_numpy(jvp_res.detach())
1123
1133
 
1124
1134
  def _predict_model_vjp(self, x, dy):
1135
+ import torch.func as torch_func
1136
+
1125
1137
  if not hasattr(self, "batched_vjp_func"):
1126
1138
  def g(_x): # fmt: skip
1127
1139
  return self.model(_x)
1128
- def single_vjp(_x, _v): # fmt: skip
1129
- out, f = self.torch_func.vjp(g, _x)
1140
+
1141
+ def single_vjp(_x, _v):
1142
+ out, f = torch_func.vjp(g, _x)
1130
1143
  return out, f(_v)
1131
- self.batched_vjp_func = self.torch_func.vmap(single_vjp)
1144
+
1145
+ self.batched_vjp_func = torch_func.vmap(single_vjp)
1132
1146
 
1133
1147
  x = self.__to_tensor(x)
1134
1148
  dy = self.__to_tensor(dy)
@@ -1136,49 +1150,50 @@ class PyTorchModel(SurrogateModel):
1136
1150
  return self.__to_numpy(output.detach()), self.__to_numpy(vjp_res[0].detach())
1137
1151
 
1138
1152
  def _predict_model_output_and_jacobian_fwd(self, x):
1153
+ import torch.func as torch_func
1154
+
1139
1155
  if not hasattr(self, "y_jac_fwd_func"):
1140
1156
  def g(_x): # fmt: skip
1141
1157
  result = self.model(_x)
1142
1158
  return (result, result)
1143
- self.y_jac_fwd_func = self.torch_func.vmap(
1144
- self.torch_func.jacfwd(g, has_aux=True)
1145
- )
1159
+ self.y_jac_fwd_func = torch_func.vmap(torch_func.jacfwd(g, has_aux=True))
1146
1160
 
1147
1161
  x = self.__to_tensor(x)
1148
1162
  jac, output = self.y_jac_fwd_func(x)
1149
1163
  return self.__to_numpy(output.detach()), self.__to_numpy(jac.detach())
1150
1164
 
1151
1165
  def _predict_model_output_and_jacobian_rev(self, x):
1166
+ import torch.func as torch_func
1167
+
1152
1168
  if not hasattr(self, "y_jac_rev_func"):
1153
1169
  def g(_x): # fmt: skip
1154
1170
  result = self.model(_x)
1155
1171
  return (result, result)
1156
- self.y_jac_rev_func = self.torch_func.vmap(
1157
- self.torch_func.jacrev(g, has_aux=True)
1158
- )
1172
+ self.y_jac_rev_func = torch_func.vmap(torch_func.jacrev(g, has_aux=True))
1159
1173
 
1160
1174
  x = self.__to_tensor(x)
1161
1175
  jac, output = self.y_jac_rev_func(x)
1162
1176
  return self.__to_numpy(output.detach()), self.__to_numpy(jac.detach())
1163
1177
 
1164
1178
  def _predict_model_jacobian_sbatch(self, x): # pragma: no cover
1165
- """Not used for now, but left as a reference for future if GPU memory issues arise."""
1179
+ # Not used for now, but left as a reference for future if GPU memory issues arise.
1180
+ import torch
1181
+ import torch.func as torch_func
1182
+
1166
1183
  if not hasattr(self, "y_jac_func"):
1167
1184
  def g(_x): # fmt: skip
1168
1185
  result = self.model(_x)
1169
1186
  return (result, result)
1170
- self.y_jac_func = self.torch_func.vmap(
1171
- self.torch_func.jacrev(g, has_aux=True)
1172
- )
1187
+ self.y_jac_func = torch_func.vmap(torch_func.jacrev(g, has_aux=True))
1173
1188
 
1174
1189
  x = self.__to_tensor(x)
1175
1190
  batch_size = x.shape[0]
1176
- y = self.torch.zeros(
1191
+ y = torch.zeros(
1177
1192
  (batch_size, self.n_outputs),
1178
1193
  device=self.device,
1179
1194
  dtype=self.dtype,
1180
1195
  )
1181
- jac = self.torch.zeros(
1196
+ jac = torch.zeros(
1182
1197
  (batch_size, self.n_outputs, self.n_inputs),
1183
1198
  device=self.device,
1184
1199
  dtype=self.dtype,