diff --git a/deeponet_acoustics/datahandlers/datagenerators.py b/deeponet_acoustics/datahandlers/datagenerators.py index cc12ccb..49c1345 100644 --- a/deeponet_acoustics/datahandlers/datagenerators.py +++ b/deeponet_acoustics/datahandlers/datagenerators.py @@ -23,79 +23,129 @@ from deeponet_acoustics.models.datastructures import SimulationDataType -class DataInterface(ABC): - @property - @abstractmethod - def simulationDataType(self) -> SimulationDataType: - """Type of the simulation data.""" - pass +def _calculate_u_pressure_minmax( + datasets: list, tag_ufield: str, max_samples: int = 500 +) -> tuple[float, float]: + """Calculate min and max pressure values from datasets. + + Args: + datasets: List of datasets (h5py.File or mock objects) + tag_ufield: Tag/key for accessing pressure data in datasets + max_samples: Maximum number of samples to use for estimation (default: 500) + + Returns: + Tuple of (p_min, p_max) as floats + """ + num_samples = min(max_samples, len(datasets)) + p_min_vals = [] + p_max_vals = [] - @property - @abstractmethod - def datasets(self) -> list[h5py.File]: - """list of h5py files.""" - pass + print(f"Estimating pressure min/max from {num_samples} samples...") + for i in range(num_samples): + upressures = datasets[i][tag_ufield][:] + p_min_vals.append(np.min(upressures)) + p_max_vals.append(np.max(upressures)) - @property - @abstractmethod - def mesh(self) -> np.ndarray: - """Mesh data (non-uniform).""" - pass + p_min = float(np.min(p_min_vals)) + p_max = float(np.max(p_max_vals)) + print(f"Pressure range: [{p_min:.4f}, {p_max:.4f}]") - @property - @abstractmethod - def tags_field(self) -> list[str]: - """Field tags for time/coordinate inputs.""" - pass + return p_min, p_max - @property - @abstractmethod - def tag_ufield(self) -> str: - """Unique field tag for input function (uniformly distributed).""" - pass - @property - @abstractmethod - def tt(self) -> np.ndarray: - """Time values""" - pass +def _normalize_spatial(data: np.ndarray, xmin: float, xmax: float) -> np.ndarray: + """Normalize spatial coordinates to [-1, 1] range. - @property - @abstractmethod - def data_prune(self) -> int: - """Pruning parameter.""" - pass + Args: + data: Data to normalize + xmin: Minimum value for normalization + xmax: Maximum value for normalization - @property - @abstractmethod - def N(self) -> int: - """Number of sources.""" - pass + Returns: + Normalized data in [-1, 1] range + """ + return 2 * (data - xmin) / (xmax - xmin) - 1 - @property - @abstractmethod - def u_shape(self) -> list[int]: - """Shape of the input function of the initial condition.""" - pass + +def _normalize_temporal(data: np.ndarray, xmin: float, xmax: float) -> np.ndarray: + """Normalize temporal coordinates. + + Args: + data: Data to normalize + xmin: Minimum spatial value for normalization + xmax: Maximum spatial value for normalization + + Returns: + Normalized temporal data + """ + return data / (xmax - xmin) / 2 + + +def _denormalize_spatial(data: np.ndarray, xmin: float, xmax: float) -> np.ndarray: + """Denormalize spatial coordinates from [-1, 1] range. + + Args: + data: Normalized data to denormalize + xmin: Minimum value for denormalization + xmax: Maximum value for denormalization + + Returns: + Denormalized spatial data + """ + return (data + 1) / 2 * (xmax - xmin) + xmin + + +def _denormalize_temporal(data: np.ndarray, xmin: float, xmax: float) -> np.ndarray: + """Denormalize temporal coordinates. + + Args: + data: Normalized data to denormalize + xmin: Minimum spatial value for denormalization + xmax: Maximum spatial value for denormalization + + Returns: + Denormalized temporal data + """ + return data * 2 * (xmax - xmin) + + +class DataInterface(ABC): + # Required attributes that concrete classes must define + simulationDataType: SimulationDataType + datasets: list[h5py.File] + mesh: np.ndarray + tags_field: list[str] + tag_ufield: str + tt: np.ndarray + data_prune: int + N: int + u_shape: np.ndarray | list[int] + tsteps: np.ndarray @property @abstractmethod - def P(self) -> np.ndarray: + def P(self) -> int: """Total number of time/space points.""" pass - @property @abstractmethod - def tsteps(self) -> np.ndarray: - """Time steps.""" + def u_pressures(self, idx: int) -> np.ndarray: + """Get normalized u pressures for a given dataset index.""" pass class DataXdmf(DataInterface): simulationDataType: SimulationDataType = SimulationDataType.XDMF - P: int - Pmesh: int + datasets: list[h5py.File] + mesh: np.ndarray + u_shape: list[int] + tsteps: np.ndarray + tt: np.ndarray + tags_field: list[str] + tag_ufield: str + data_prune: int + N: int xmin: float xmax: float @@ -116,108 +166,92 @@ def __init__( # NOTE: we assume meshes, tags, etc are the same across all xdmf datasets xdmf = XdmfReader(filenames_xdmf[0], tmax=tmax / t_norm) - self._tags_field = xdmf.tags_field - self._tag_ufield = xdmf.tag_ufield - self._data_prune = data_prune - self._tsteps = xdmf.tsteps * t_norm + self.tags_field = xdmf.tags_field + self.tag_ufield = xdmf.tag_ufield + self.data_prune = data_prune + self.tsteps = xdmf.tsteps * t_norm with h5py.File(xdmf.filenameH5) as r: - self._mesh = np.array(r[xdmf.tag_mesh][:: self._data_prune]) - self.xmin, self.xmax = np.min(self._mesh), np.max(self._mesh) + self.mesh = np.array(r[xdmf.tag_mesh][:: self.data_prune]) + self.xmin, self.xmax = np.min(self.mesh), np.max(self.mesh) umesh_obj = r[xdmf.tag_umesh] umesh = np.array(umesh_obj[:]) - self._u_shape = ( + self.u_shape = ( [len(umesh)] if flatten_ic else jnp.array(umesh_obj.attrs[xdmf.tag_ushape][:], dtype=int).tolist() ) if norm_data: - self._mesh = self.normalizeSpatial(self._mesh) - self._tsteps = self.normalizeTemporal(self._tsteps) + self.mesh = self.normalize_spatial(self.mesh) + self.tsteps = self.normalize_temporal(self.tsteps) - self._tt = np.repeat(self._tsteps, self._mesh.shape[0]) + self.tt = np.repeat(self.tsteps, self.mesh.shape[0]) - self._datasets = [] + self.datasets = [] for i in range(0, min(MAXNUM_DATASETS, len(filenames_xdmf))): filename = filenames_xdmf[i] if Path(filename).exists(): xdmf = XdmfReader(filename, tmax / t_norm) - self._datasets.append( + self.datasets.append( h5py.File(xdmf.filenameH5, "r") ) # add file handles and keeps open else: print(f"Could not be found (ignoring): {filename}") - self._N = len(self._datasets) - - # --- required abstract properties implemented --- - @property - def datasets(self): - return self._datasets - - @property - def mesh(self): - return self._mesh - - @property - def u_shape(self): - return self._u_shape - - @property - def tsteps(self): - return self._tsteps - - @property - def tt(self): - return self._tt - - @property - def tags_field(self): - return self._tags_field - - @property - def tag_ufield(self): - return self._tag_ufield + self.N = len(self.datasets) - @property - def data_prune(self): - return self._data_prune - - @property - def N(self): - return self._N + # Calculate min and max pressure values from sampled datasets + self._u_p_min, self._u_p_max = _calculate_u_pressure_minmax( + self.datasets, self.tag_ufield + ) + # --- required abstract properties implemented --- @property - def Pmesh(self): + def P_mesh(self): """Total number of mesh points.""" return self.mesh.shape[0] @property def P(self): """Total number of time/space points.""" - return self.Pmesh * self.tsteps.shape[0] + return self.P_mesh * len(self.tsteps) - def normalizeSpatial(self, data): - return 2 * (data - self.xmin) / (self.xmax - self.xmin) - 1 + def normalize_spatial(self, data): + return _normalize_spatial(data, self.xmin, self.xmax) - def normalizeTemporal(self, data): - return data / (self.xmax - self.xmin) / 2 + def normalize_temporal(self, data): + return _normalize_temporal(data, self.xmin, self.xmax) + + def u_pressures(self, idx: int) -> np.ndarray: + """Get normalized u pressures for a given dataset index.""" + dataset = self.datasets[idx] + u_norm = _normalize_spatial( + dataset[self.tag_ufield][:], self._u_p_min, self._u_p_max + ) + return jnp.reshape(u_norm, self.u_shape) def __del__(self): - for dataset in self._datasets: + for dataset in self.datasets: dataset.close() class DataH5Compact(DataInterface): simulationDataType: SimulationDataType = SimulationDataType.H5COMPACT - P: int - Pmesh: int + datasets: list[h5py.File] + mesh: np.ndarray + u_shape: np.ndarray + tsteps: np.ndarray + tt: np.ndarray + tags_field: list[str] + tag_ufield: str + data_prune: int + N: int + xmin: float xmax: float normalize_data: bool - conn: np.ndarray # MAXNUM_DATASETS: SET TO E.G: 500 WHEN DEBUGGING ON MACHINES WITH LESS RESOURCES @@ -232,7 +266,7 @@ def __init__( MAXNUM_DATASETS=sys.maxsize, ): filenamesH5 = IO.pathsToFileType(data_path, ".h5", exclude="rectilinear") - self._data_prune = data_prune + self.data_prune = data_prune self.normalize_data = norm_data # NOTE: we assume meshes, tags, etc are the same accross all xdmf datasets @@ -240,112 +274,89 @@ def __init__( tag_conn = "/conn" tag_umesh = "/umesh" tag_ushape = "umesh_shape" - self._tags_field = ["/pressures"] - self._tag_ufield = "/upressures" + self.tags_field = ["/pressures"] + self.tag_ufield = "/upressures" with h5py.File(filenamesH5[0]) as r: - self._mesh = np.array(r[tag_mesh][:: self._data_prune]) + self.mesh = np.array(r[tag_mesh][:: self.data_prune]) self.conn = ( np.array(r[tag_conn]) - if self._data_prune == 1 and tag_conn in r + if self.data_prune == 1 and tag_conn in r else np.array([]) ) - self.xmin, self.xmax = np.min(self._mesh), np.max(self._mesh) + self.xmin, self.xmax = np.min(self.mesh), np.max(self.mesh) umesh_obj = r[tag_umesh] umesh = np.array(umesh_obj[:]) - self._u_shape = ( + self.u_shape = ( jnp.array([len(umesh)], dtype=int) if flatten_ic else jnp.array(umesh_obj.attrs[tag_ushape][:], dtype=int) ) - self._tsteps = r[self._tags_field[0]].attrs["time_steps"] - self._tsteps = jnp.array([t for t in self._tsteps if t <= tmax / t_norm]) - self._tsteps = self._tsteps * t_norm + self.tsteps = r[self.tags_field[0]].attrs["time_steps"] + self.tsteps = jnp.array([t for t in self.tsteps if t <= tmax / t_norm]) + self.tsteps = self.tsteps * t_norm if self.normalize_data: - self._mesh = self.normalizeSpatial(self._mesh) - self._tsteps = self.normalizeTemporal(self._tsteps) + self.mesh = self.normalize_spatial(self.mesh) + self.tsteps = self.normalize_temporal(self.tsteps) - self._tt = np.repeat(self._tsteps, self._mesh.shape[0]) - self._N = len(filenamesH5) + self.tt = np.repeat(self.tsteps, self.mesh.shape[0]) + self.N = len(filenamesH5) - self._datasets = [] + self.datasets = [] for i in range(0, min(MAXNUM_DATASETS, len(filenamesH5))): filename = filenamesH5[i] if Path(filename).exists(): - self._datasets.append( + self.datasets.append( h5py.File(filename, "r") ) # add file handles and keeps open else: print(f"Could not be found (ignoring): {filename}") - # --- required abstract properties implemented --- - @property - def datasets(self): - return self._datasets - - @property - def mesh(self): - return self._mesh - - @property - def u_shape(self): - return self._u_shape - - @property - def tsteps(self): - return self._tsteps - - @property - def tt(self): - return self._tt - - @property - def tags_field(self): - return self._tags_field - - @property - def tag_ufield(self): - return self._tag_ufield - - @property - def data_prune(self): - return self._data_prune - - @property - def N(self): - return self._N + # Calculate min and max pressure values from sampled datasets + self._u_p_min, self._u_p_max = _calculate_u_pressure_minmax( + self.datasets, self.tag_ufield + ) + # --- required abstract properties implemented --- @property - def Pmesh(self): + def P_mesh(self): """Total number of mesh points.""" return self.mesh.shape[0] @property def P(self): """Total number of time/space points.""" - return self.Pmesh * self.tsteps.shape[0] + return self.P_mesh * len(self.tsteps) @property def xxyyzztt(self): xxyyzz = np.tile(self.mesh, (len(self.tsteps), 1)) return np.hstack((xxyyzz, self.tt.reshape(-1, 1))) - def normalizeSpatial(self, data): - return 2 * (data - self.xmin) / (self.xmax - self.xmin) - 1 + def normalize_spatial(self, data): + return _normalize_spatial(data, self.xmin, self.xmax) - def normalizeTemporal(self, data): - return data / (self.xmax - self.xmin) / 2 + def normalize_temporal(self, data): + return _normalize_temporal(data, self.xmin, self.xmax) - def denormalizeSpatial(self, data): - return (data + 1) / 2 * (self.xmax - self.xmin) + self.xmin + def denormalize_spatial(self, data): + return _denormalize_spatial(data, self.xmin, self.xmax) - def denormalizeTemporal(self, data): - return data * 2 * (self.xmax - self.xmin) + def denormalize_temporal(self, data): + return _denormalize_temporal(data, self.xmin, self.xmax) + + def u_pressures(self, idx: int) -> np.ndarray: + """Get normalized u pressures for a given dataset index.""" + dataset = self.datasets[idx] + u_norm = _normalize_spatial( + dataset[self.tag_ufield][:], self._u_p_min, self._u_p_max + ) + return jnp.reshape(u_norm, self.u_shape) def __del__(self): - for dataset in self._datasets: + for dataset in self.datasets: dataset.close() @@ -380,6 +391,17 @@ class DataSourceOnly(DataInterface): simulationDataType: SimulationDataType = SimulationDataType.SOURCE_ONLY + datasets: list[h5py.File] + mesh: np.ndarray[float] + tags_field: list[str] + tag_ufield: str + tsteps: np.ndarray[float] + tt: np.ndarray[float] + N: int + u_shape: np.ndarray[np.int64] + conn: np.ndarray[np.int64] + data_prune: int + def __init__( self, data_path: str, @@ -390,57 +412,58 @@ def __init__( flatten_ic: bool = True, data_prune: int = 1, norm_data: bool = False, - p_minmax: tuple[float, float] = (-2.0, 2.0), ) -> None: - self._data_prune = data_prune + self.data_prune = data_prune self._normalize_data = norm_data tag_mesh = "/mesh" tag_conn = "/conn" tag_umesh = "/umesh" tag_ushape = "umesh_shape" - self._tags_field = ["/pressures"] - self._tag_ufield = "/upressures" + self.tags_field = ["/pressures"] + self.tag_ufield = "/upressures" filenamesH5 = IO.pathsToFileType(data_path, ".h5", exclude="rectilinear") + gauss_amplitude = 1.0 + with h5py.File(filenamesH5[0]) as r: - self._mesh = np.array(r[tag_mesh][:: self._data_prune]) - self._conn = ( + self.mesh = np.array(r[tag_mesh][:: self.data_prune]) + self.conn = ( np.array(r[tag_conn]) - if self._data_prune == 1 and tag_conn in r + if self.data_prune == 1 and tag_conn in r else np.array([]) ) self._xmin, self._xmax = ( - float(np.min(self._mesh)), - float(np.max(self._mesh)), + float(np.min(self.mesh)), + float(np.max(self.mesh)), ) umesh_obj = r[tag_umesh] if flatten_ic: - self._u_shape = jnp.array([len(umesh_obj[:])], dtype=int) + self.u_shape = jnp.array([len(umesh_obj[:])], dtype=int) else: - self._u_shape = jnp.array(umesh_obj.attrs[tag_ushape][:], dtype=int) + self.u_shape = jnp.array(umesh_obj.attrs[tag_ushape][:], dtype=int) - tsteps = r[self._tags_field[0]].attrs["time_steps"] + tsteps = r[self.tags_field[0]].attrs["time_steps"] tsteps = jnp.array([t for t in tsteps if t <= tmax / t_norm]) - self._tsteps = tsteps * t_norm + self.tsteps = tsteps * t_norm if self._normalize_data: - self._mesh = self.normalizeSpatial(self._mesh) - self._tsteps = self.normalizeTemporal(self._tsteps) + self.mesh = self.normalize_spatial(self.mesh) + self.tsteps = self.normalize_temporal(self.tsteps) gaussianSrc = lambda x, y, z, xyz0, sigma, ampl: ampl * np.exp( -((x - xyz0[0]) ** 2 + (y - xyz0[1]) ** 2 + (z - xyz0[2]) ** 2) / sigma**2 ) - self._datasets: list[h5py.File] = [] + self.datasets: list[h5py.File] = [] sigma0 = params.c / (np.pi * params.fmax / 2) - self._N = len(source_pos) + self.N = len(source_pos) - for i in range(self._N): + for i in range(self.N): x0 = source_pos[i] ic_field = gaussianSrc( umesh_obj[:, 0], @@ -448,51 +471,28 @@ def __init__( umesh_obj[:, 2], x0, sigma0, - p_minmax[1], + gauss_amplitude, ) - self._datasets.append( - DatasetH5Mock({self._tag_ufield: ic_field, "source_position": x0}) + self.datasets.append( + DatasetH5Mock({self.tag_ufield: ic_field, "source_position": x0}) ) - self._tt = np.repeat(self._tsteps, self._mesh.shape[0]) - - @property - def datasets(self) -> list[h5py.File]: - return self._datasets - - @property - def mesh(self) -> np.ndarray[float]: - return self._mesh - - @property - def tags_field(self) -> list[str]: - return self._tags_field - - @property - def tag_ufield(self) -> str: - return self._tag_ufield - - @property - def tsteps(self) -> np.ndarray[float]: - return self._tsteps - - @property - def tt(self) -> np.ndarray[float]: - return self._tt + # Calculate min and max pressure values from generated datasets + self._u_p_min, self._u_p_max = _calculate_u_pressure_minmax( + self.datasets, self.tag_ufield, max_samples=self.N + ) - @property - def N(self) -> int: - return self._N + self.tt = np.repeat(self.tsteps, self.mesh.shape[0]) @property - def Pmesh(self) -> int: + def P_mesh(self) -> int: """Total number of mesh points.""" return self.mesh.shape[0] @property def P(self) -> int: """Total number of time/space points.""" - return self.Pmesh * self.tsteps.shape[0] + return self.P_mesh * len(self.tsteps) @property def xmin(self) -> float: @@ -506,34 +506,34 @@ def xmax(self) -> float: def normalize_data(self) -> bool: return self._normalize_data - @property - def u_shape(self) -> np.ndarray[np.int64]: - return self._u_shape - - @property - def conn(self) -> np.ndarray[np.int64]: - return self._conn - @property def xxyyzztt(self) -> np.ndarray[float]: """Spatio-temporal coordinates stacked as [x, y, z, t].""" xxyyzz = np.tile(self.mesh, (len(self.tsteps), 1)) return np.hstack((xxyyzz, self.tt.reshape(-1, 1))) - def normalizeSpatial(self, data: np.ndarray[float]) -> np.ndarray[float]: - return 2 * (data - self._xmin) / (self._xmax - self._xmin) - 1 + def normalize_spatial(self, data: np.ndarray[float]) -> np.ndarray[float]: + return _normalize_spatial(data, self._xmin, self._xmax) + + def normalize_temporal(self, data: np.ndarray[float]) -> np.ndarray[float]: + return _normalize_temporal(data, self._xmin, self._xmax) - def normalizeTemporal(self, data: np.ndarray[float]) -> np.ndarray[float]: - return data / (self._xmax - self._xmin) / 2 + def denormalize_spatial(self, data: np.ndarray[float]) -> np.ndarray[float]: + return _denormalize_spatial(data, self._xmin, self._xmax) - def denormalizeSpatial(self, data: np.ndarray[float]) -> np.ndarray[float]: - return (data + 1) / 2 * (self._xmax - self._xmin) + self._xmin + def denormalize_temporal(self, data: np.ndarray[float]) -> np.ndarray[float]: + return _denormalize_temporal(data, self._xmin, self._xmax) - def denormalizeTemporal(self, data: np.ndarray[float]) -> np.ndarray[float]: - return data * 2 * (self._xmax - self._xmin) + def u_pressures(self, idx: int) -> np.ndarray: + """Get normalized u pressures for a given dataset index.""" + dataset = self.datasets[idx] + u_norm = _normalize_spatial( + dataset[self.tag_ufield], self._u_p_min, self._u_p_max + ) + return jnp.reshape(u_norm, self.u_shape) def close(self) -> None: - for dataset in self._datasets: + for dataset in self.datasets: dataset.close() def __del__(self) -> None: @@ -541,17 +541,12 @@ def __del__(self) -> None: class DatasetStreamer(Dataset): - Pmesh: int + P_mesh: int P: int batch_size_coord: int - data: DataInterface - p_minmax: tuple[float, float] - itercount: itertools.count - __y_feat_extract_fn = Callable[[list], list] - total_time = 0 @property @@ -559,21 +554,18 @@ def N(self): return self.data.N @property - def Pmesh(self): + def P_mesh(self): """Total number of mesh points.""" return self.data.mesh.shape[0] @property def P(self): """Total number of time/space points.""" - return self.Pmesh * self.data.tsteps.shape[0] + return self.P_mesh * self.data.tsteps.shape[0] - def __init__( - self, data, batch_size_coord=-1, y_feat_extract_fn=None, p_minmax=(-2.0, 2.0) - ): + def __init__(self, data, batch_size_coord=-1, y_feat_extract_fn=None): # batch_size_coord: set to -1 if full dataset should be used (e.g. for validation data) self.data = data - self.p_minmax = p_minmax self.batch_size_coord = ( batch_size_coord if batch_size_coord <= self.P else self.P @@ -590,13 +582,7 @@ def __len__(self): def __getitem__(self, idx): dataset = self.data.datasets[idx] - u_norm = ( - 2 - * (dataset[self.data.tag_ufield][:] - self.p_minmax[0]) - / (self.p_minmax[1] - self.p_minmax[0]) - - 1 - ) - u = jnp.reshape(u_norm, self.data.u_shape) + u = self.data.u_pressures(idx) start_time_0 = time.perf_counter() if self.batch_size_coord > 0: @@ -608,7 +594,7 @@ def __getitem__(self, idx): end_time_0 = time.perf_counter() self.total_time += end_time_0 - start_time_0 - xxyyzz = self.data.mesh[np.mod(indxs_coord, self.data.Pmesh), :] + xxyyzz = self.data.mesh[np.mod(indxs_coord, self.data.P_mesh), :] tt = self.data.tt[indxs_coord].reshape(-1, 1) y = self.__y_feat_extract_fn(np.hstack((xxyyzz, tt))) @@ -622,7 +608,7 @@ def __getitem__(self, idx): elif self.data.simulationDataType == SimulationDataType.XDMF: s = np.empty((self.P), dtype=jnp.float32) for j in range(num_tsteps): - s[j * self.data.Pmesh : (j + 1) * self.Pmesh] = dataset[ + s[j * self.data.P_mesh : (j + 1) * self.P_mesh] = dataset[ self.data.tags_field[j] ][:: self.data.data_prune] s = s[indxs_coord] @@ -633,7 +619,7 @@ def __getitem__(self, idx): # normalize x0 = ( - self.data.normalizeSpatial(dataset["source_position"][:]) + self.data.normalize_spatial(dataset["source_position"][:]) if "source_position" in dataset else [] ) @@ -642,7 +628,7 @@ def __getitem__(self, idx): return inputs, jnp.asarray(s), indxs_coord, x0 -def getNumberOfSources(data_path: str): +def get_number_of_sources(data_path: str): return len(IO.pathsToFileType(data_path, ".h5", exclude="rectilinear")) diff --git a/deeponet_acoustics/end2end/inference.py b/deeponet_acoustics/end2end/inference.py index 6f29b32..699a01e 100644 --- a/deeponet_acoustics/end2end/inference.py +++ b/deeponet_acoustics/end2end/inference.py @@ -20,7 +20,7 @@ DataH5Compact, DatasetStreamer, DataSourceOnly, - getNumberOfSources, + get_number_of_sources, ) from deeponet_acoustics.models.datastructures import ( EvaluationSettings, @@ -48,7 +48,7 @@ def inference( settings_eval = EvaluationSettings(settings_eval_dict) else: # we read number of sources from filesystem when not explicitly set - num_srcs = getNumberOfSources(settings_eval_dict["validation_data_dir"]) + num_srcs = get_number_of_sources(settings_eval_dict["validation_data_dir"]) settings_eval = EvaluationSettings(settings_eval_dict, num_srcs) tmax = settings_eval.tmax @@ -136,16 +136,16 @@ def inference( xxyyzztt = metadata.xxyyzztt y_in = y_feat_fn(xxyyzztt) - xxyyzz_phys = metadata.denormalizeSpatial(xxyyzztt[:, 0:3]) - mesh_phys = metadata.denormalizeSpatial(metadata.mesh) - tsteps_phys = metadata.denormalizeTemporal(metadata.tsteps / c_phys) + xxyyzz_phys = metadata.denormalize_spatial(xxyyzztt[:, 0:3]) + mesh_phys = metadata.denormalize_spatial(metadata.mesh) + tsteps_phys = metadata.denormalize_temporal(metadata.tsteps / c_phys) num_srcs = dataset.N ############## WRITE FULL WAVE FIELD ############## if settings_eval.write_full_wave_field: - S_pred_srcs = np.empty((num_srcs, tdim, dataset.Pmesh), dtype=float) - S_test_srcs = np.empty((num_srcs, tdim, dataset.Pmesh), dtype=float) + S_pred_srcs = np.empty((num_srcs, tdim, dataset.P_mesh), dtype=float) + S_test_srcs = np.empty((num_srcs, tdim, dataset.P_mesh), dtype=float) for i_src in range(num_srcs): (u_test_i, *_), s_test_i, _, x0 = dataset[i_src] @@ -159,7 +159,7 @@ def inference( S_pred_srcs[i_src, :, :] = np.asarray(s_pred_i) S_test_srcs[i_src, :, :] = np.asarray(s_test_i).reshape(tdim, -1) - x0 = metadata.denormalizeSpatial(x0) + x0 = metadata.denormalize_spatial(x0) IO.writeTetraXdmf( mesh_phys, @@ -193,11 +193,11 @@ def inference( ir_ref_srcs = [] for i_src in range(num_srcs): - r0_list_norm = metadata.normalizeSpatial(r0_list[i_src]) + r0_list_norm = metadata.normalize_spatial(r0_list[i_src]) (u_test_i, *_), s_test_i, _, x0 = dataset[i_src] - x0 = metadata.denormalizeSpatial(x0) + x0 = metadata.denormalize_spatial(x0) x0_srcs.append(x0) y_rcvs = np.repeat(np.array(r0_list_norm), len(metadata.tsteps), axis=0) diff --git a/tests/integration/test_end2end_2d.py b/tests/integration/test_end2end_2d.py index 780d171..c63f8ad 100644 --- a/tests/integration/test_end2end_2d.py +++ b/tests/integration/test_end2end_2d.py @@ -285,7 +285,7 @@ def test_data_loading_consistency(self, small_2d_dataset): # Check basic properties assert data.N == 3 assert data.mesh.shape[1] == 2 # 2D - assert data.Pmesh == 15 * 15 # nx * ny + assert data.P_mesh == 15 * 15 # nx * ny assert len(data.tsteps) == 12 # Test dataset streamer diff --git a/tests/unit/test_datagenerators.py b/tests/unit/test_datagenerators.py index 463ebfe..6167d96 100644 --- a/tests/unit/test_datagenerators.py +++ b/tests/unit/test_datagenerators.py @@ -15,6 +15,7 @@ from deeponet_acoustics.datahandlers.datagenerators import ( DataH5Compact, DatasetStreamer, + _calculate_u_pressure_minmax, numpy_collate, ) from deeponet_acoustics.models.datastructures import SimulationDataType @@ -37,7 +38,7 @@ def test_initialization(self, mock_h5_dataset_2d): assert data.mesh.shape[1] == 2 # 2D data assert len(data.datasets) == len(files) assert data.P > 0 - assert data.Pmesh > 0 + assert data.P_mesh > 0 def test_mesh_properties(self, mock_h5_dataset_2d): """Test mesh properties and dimensions.""" @@ -46,8 +47,8 @@ def test_mesh_properties(self, mock_h5_dataset_2d): data = DataH5Compact(str(data_path), flatten_ic=True) assert data.mesh.ndim == 2 - assert data.Pmesh == data.mesh.shape[0] - assert data.P == data.Pmesh * len(data.tsteps) + assert data.P_mesh == data.mesh.shape[0] + assert data.P == data.P_mesh * len(data.tsteps) assert len(data.tt) == data.P def test_data_pruning(self, mock_h5_dataset_2d): @@ -58,8 +59,8 @@ def test_data_pruning(self, mock_h5_dataset_2d): data_pruned = DataH5Compact(str(data_path), data_prune=2) # Pruned data should have fewer mesh points - assert data_pruned.Pmesh < data_full.Pmesh - assert data_pruned.Pmesh == (data_full.Pmesh + 1) // 2 + assert data_pruned.P_mesh < data_full.P_mesh + assert data_pruned.P_mesh == (data_full.P_mesh + 1) // 2 def test_time_truncation(self, mock_h5_dataset_2d): """Test time truncation with tmax parameter.""" @@ -102,13 +103,13 @@ def test_spatial_normalization_functions(self, mock_h5_dataset_2d): # Test spatial normalization test_coords = np.array([[data.xmin, data.xmin], [data.xmax, data.xmax]]) - normalized = data.normalizeSpatial(test_coords) + normalized = data.normalize_spatial(test_coords) # Check boundaries map to [-1, 1] assert np.allclose(normalized, [[-1, -1], [1, 1]]) # Test round-trip - denormalized = data.denormalizeSpatial(normalized) + denormalized = data.denormalize_spatial(normalized) assert np.allclose(test_coords, denormalized) def test_temporal_normalization_functions(self, mock_h5_dataset_2d): @@ -119,10 +120,10 @@ def test_temporal_normalization_functions(self, mock_h5_dataset_2d): # Test temporal normalization test_times = np.array([0.0, 1.0, 2.0]) - normalized = data.normalizeTemporal(test_times) + normalized = data.normalize_temporal(test_times) assert np.min(normalized.flatten()) == 0 - denormalized = data.denormalizeTemporal(normalized) + denormalized = data.denormalize_temporal(normalized) # Check round-trip assert np.allclose(test_times, denormalized) @@ -172,7 +173,7 @@ def test_initialization(self, mock_h5_dataset_2d): assert len(dataset) == len(files) assert dataset.N == len(files) assert dataset.P == data.P - assert dataset.Pmesh == data.Pmesh + assert dataset.P_mesh == data.P_mesh def test_getitem(self, mock_h5_dataset_2d): """Test getting individual items from dataset.""" @@ -287,3 +288,64 @@ def test_collate_nested(self): assert isinstance(result, list) assert len(result) == 2 assert isinstance(result[0], list) + + +@pytest.mark.unit +class TestUPressures: + """Test suite for u_pressures functionality.""" + + def test_calculate_u_pressure_minmax(self): + """Test basic min/max calculation with mock datasets.""" + + # Create mock datasets with known min/max values + class MockDataset: + def __init__(self, data): + self.data = {"/upressures": data} + + def __getitem__(self, key): + return self.data[key] + + # Create datasets with known ranges + datasets = [ + MockDataset(np.array([-1.5, 0.0, 1.5])), + MockDataset(np.array([-2.0, 0.5, 2.0])), + MockDataset(np.array([-1.0, 0.0, 1.0])), + ] + + p_min, p_max = _calculate_u_pressure_minmax(datasets, "/upressures") + + assert p_min == -2.0 + assert p_max == 2.0 + + def test_u_pressures_normalization(self, mock_h5_dataset_2d): + """Test that u_pressures returns properly normalized values.""" + data_path, _ = mock_h5_dataset_2d + + data = DataH5Compact(str(data_path)) + + # Get normalized pressures + u_norm = data.u_pressures(0) + + # Should be normalized to [-1, 1] + assert np.all(u_norm >= -1.0) + assert np.all(u_norm <= 1.0) + + # Check shape matches u_shape + assert u_norm.shape == tuple(data.u_shape) + + def test_u_pressures_different_indices(self, mock_h5_dataset_2d): + """Test u_pressures with different dataset indices.""" + data_path, _ = mock_h5_dataset_2d + + data = DataH5Compact(str(data_path)) + + # Get pressures for different indices + u0 = data.u_pressures(0) + u1 = data.u_pressures(1) + + # Should have same shape + assert u0.shape == u1.shape + + # Should both be normalized + assert np.all(u0 >= -1.0) and np.all(u0 <= 1.0) + assert np.all(u1 >= -1.0) and np.all(u1 <= 1.0) diff --git a/tests/unit/test_deeponet.py b/tests/unit/test_deeponet.py index 530a758..c1f36d2 100644 --- a/tests/unit/test_deeponet.py +++ b/tests/unit/test_deeponet.py @@ -92,7 +92,7 @@ class MockDataset: N = 10 # Number of sources P = 500 # Total coordinate points u_shape = [50] # Input shape - Pmesh = 50 + P_mesh = 50 tsteps = np.linspace(0, 1, 10) def __init__(self): diff --git a/uv.lock b/uv.lock index 12c4453..b1f7cd5 100644 --- a/uv.lock +++ b/uv.lock @@ -496,7 +496,7 @@ dependencies = [ [package.optional-dependencies] cuda12 = [ - { name = "jax", extra = ["cuda12"] }, + { name = "jax" }, { name = "jaxlib" }, ] test = [ @@ -510,7 +510,7 @@ requires-dist = [ { name = "graphviz" }, { name = "h5py" }, { name = "jax", extras = ["cpu"], specifier = ">=0.6.2" }, - { name = "jax", extras = ["cuda12"], marker = "extra == 'cuda12'", specifier = "==0.7.2" }, + { name = "jax", extras = ["local-cuda12"], marker = "extra == 'cuda12'", specifier = "==0.7.2" }, { name = "jaxlib" }, { name = "jaxlib", marker = "extra == 'cuda12'", specifier = "==0.7.2" }, { name = "matplotlib" }, @@ -1071,59 +1071,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/e6/5fd0f6fff79eb47469ff9c4fa27125b661517a2fbf8884689b02e9fdfaa8/jax-0.7.2-py3-none-any.whl", hash = "sha256:e7e32f9be51ae5cc6854225958c57de8cca2187d279844338465b15e8a1fe7f2", size = 2835570, upload-time = "2025-09-16T16:48:51.33Z" }, ] -[package.optional-dependencies] -cuda12 = [ - { name = "jax-cuda12-plugin", extra = ["with-cuda"] }, - { name = "jaxlib" }, -] - -[[package]] -name = "jax-cuda12-pjrt" -version = "0.7.2" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/a3/f5e6cdfb3fe3ff0285becf08edb84345bd71913102c77ccf9fe71816e7c7/jax_cuda12_pjrt-0.7.2-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:d87d666d0c523fadaadb7194e7c274dcc5a0e7f8f8d1d7e2835353ef32bef01c", size = 125832574, upload-time = "2025-09-16T16:50:22.053Z" }, - { url = "https://files.pythonhosted.org/packages/fa/64/b8653c36cb1075b34d9661a354d3b4c2db9e01a34cecbae3c5b4c2d1caf8/jax_cuda12_pjrt-0.7.2-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:3977726a2a332b0bd34831bdeb2b5653363442f3012c2996fc88080aaf6b3bad", size = 132725132, upload-time = "2025-09-16T16:50:27.521Z" }, -] - -[[package]] -name = "jax-cuda12-plugin" -version = "0.7.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jax-cuda12-pjrt" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/35/1a/a6e94d7c8cc8fc67ed3f51245dfc7844a4dced7a2e974d40bdcdb7964be8/jax_cuda12_plugin-0.7.2-cp311-cp311-manylinux_2_27_aarch64.whl", hash = "sha256:2a727a89ae69ac21c1f5093d8d5aef89a0e692e66b034fc934c8accc72e40290", size = 5466351, upload-time = "2025-09-16T17:01:47.746Z" }, - { url = "https://files.pythonhosted.org/packages/f1/b8/56708eff0065bf68cc5c738f5bdfbec4bd76ceddbef3bfaf9ac869bcbd2f/jax_cuda12_plugin-0.7.2-cp311-cp311-manylinux_2_27_x86_64.whl", hash = "sha256:adc924ebc7a45c8d3400ea0118dc70a7082b2a86e35711738d403dd3815d09bf", size = 5479806, upload-time = "2025-09-16T17:01:49.911Z" }, - { url = "https://files.pythonhosted.org/packages/7e/dd/105045cb14d993b00a0ec61458f2e559d0f410955aeb8e79b1bab80fc394/jax_cuda12_plugin-0.7.2-cp312-cp312-manylinux_2_27_aarch64.whl", hash = "sha256:98a975655382858d874d6471ce97194310609d0a2a7c4283c6e07e37933b7768", size = 5460119, upload-time = "2025-09-16T17:01:51.325Z" }, - { url = "https://files.pythonhosted.org/packages/52/c7/9698f667e309ac4bf29889190f5344891eb59479002a6a3ad253bc0a1d91/jax_cuda12_plugin-0.7.2-cp312-cp312-manylinux_2_27_x86_64.whl", hash = "sha256:8284e7cf7f544906604f111702a6f0011a96df7f0113878b381bec0905172536", size = 5476864, upload-time = "2025-09-16T17:01:52.602Z" }, - { url = "https://files.pythonhosted.org/packages/4f/4a/e7deb16fba9829eb8391407b8057a0a2b4fb781035f267b2369043921fae/jax_cuda12_plugin-0.7.2-cp313-cp313-manylinux_2_27_aarch64.whl", hash = "sha256:5e3e2aa4d721fb02dd1028262aaeaec2958e45bca5c4d3512b29151b570cb425", size = 5460772, upload-time = "2025-09-16T17:01:54.035Z" }, - { url = "https://files.pythonhosted.org/packages/db/ce/970889a70a03978dc28dc6e895e054995760dd141cbe08a5229544adb21f/jax_cuda12_plugin-0.7.2-cp313-cp313-manylinux_2_27_x86_64.whl", hash = "sha256:7212c12d75b7dc51275f271827df4a6d378430c06f650e6c31c162fe9579ff12", size = 5476949, upload-time = "2025-09-16T17:01:55.67Z" }, - { url = "https://files.pythonhosted.org/packages/ca/e9/28464bb15c442085333faebf0a41370428cb2d947ad3ee631296e889e736/jax_cuda12_plugin-0.7.2-cp313-cp313t-manylinux_2_27_aarch64.whl", hash = "sha256:45d5a1cbf0b9d05318722382fc71c4cede0c028bad6aa8e53f7a7032392f719c", size = 5474728, upload-time = "2025-09-16T17:01:56.885Z" }, - { url = "https://files.pythonhosted.org/packages/bc/a4/ff0024fa1b9de7c666d218871f9408beb47fe1a036132bbd0e281375706a/jax_cuda12_plugin-0.7.2-cp313-cp313t-manylinux_2_27_x86_64.whl", hash = "sha256:05b6942985f015be82becd2cec363f0aceb25311981821d7613a51f630490e8c", size = 5485236, upload-time = "2025-09-16T17:01:58.488Z" }, - { url = "https://files.pythonhosted.org/packages/06/d0/a65d3e0375c7dc8425ef49671090f6eae23a0a8c780bd80127a4a0c25ced/jax_cuda12_plugin-0.7.2-cp314-cp314-manylinux_2_27_aarch64.whl", hash = "sha256:e881b56fe27e6870db2f2e9c574b81965fe1102b1532eae60e240a40c065daf5", size = 5461974, upload-time = "2025-09-16T17:02:00.017Z" }, - { url = "https://files.pythonhosted.org/packages/45/5c/5900fe909801469de67df6d7e99dbff93efdb9ab31219c81f124eae1f882/jax_cuda12_plugin-0.7.2-cp314-cp314-manylinux_2_27_x86_64.whl", hash = "sha256:23b8f1050c48b4020610fb818930d3cbe0304c6681b069687e5416ee349bd734", size = 5477722, upload-time = "2025-09-16T17:02:01.258Z" }, - { url = "https://files.pythonhosted.org/packages/68/38/da12a17f1f26e3d36670b2c290fcf826c55cd267f6da49aef27ed24a0401/jax_cuda12_plugin-0.7.2-cp314-cp314t-manylinux_2_27_aarch64.whl", hash = "sha256:7ad3afc51bcbc4e8117845d359e5d02cbc5ca2b152efdebd3c55fb9e4c2f848e", size = 5475355, upload-time = "2025-09-16T17:02:02.873Z" }, - { url = "https://files.pythonhosted.org/packages/d9/d1/07bf754ed5cd43e706f6d64c681e8b0de43b3235cfa2d9507f2ceb9f3bd2/jax_cuda12_plugin-0.7.2-cp314-cp314t-manylinux_2_27_x86_64.whl", hash = "sha256:1d00f9f5c5f68ae0f41cb7b589005ed5cb556517d65bbab5a891be46ed7a781c", size = 5485605, upload-time = "2025-09-16T17:02:04.505Z" }, -] - -[package.optional-dependencies] -with-cuda = [ - { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-cuda-cupti-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-cuda-nvcc-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-cuda-nvrtc-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-cuda-runtime-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-cudnn-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-cufft-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-cusolver-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-cusparse-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-nccl-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, - { name = "nvidia-nvshmem-cu12", marker = "sys_platform == 'linux'" }, -] - [[package]] name = "jaxlib" version = "0.7.2" @@ -1854,7 +1801,6 @@ name = "nvidia-cublas-cu12" version = "12.8.4.1" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/99/db44d685f0e257ff0e213ade1964fc459b4a690a73293220e98feb3307cf/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:b86f6dd8935884615a0683b663891d43781b819ac4f2ba2b0c9604676af346d0", size = 590537124, upload-time = "2025-03-07T01:43:53.556Z" }, { url = "https://files.pythonhosted.org/packages/dc/61/e24b560ab2e2eaeb3c839129175fb330dfcfc29e5203196e5541a4c44682/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142", size = 594346921, upload-time = "2025-03-07T01:44:31.254Z" }, ] @@ -1863,26 +1809,15 @@ name = "nvidia-cuda-cupti-cu12" version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/1f/b3bd73445e5cb342727fd24fe1f7b748f690b460acadc27ea22f904502c8/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4412396548808ddfed3f17a467b104ba7751e6b58678a4b840675c56d21cf7ed", size = 9533318, upload-time = "2025-03-07T01:40:10.421Z" }, { url = "https://files.pythonhosted.org/packages/f8/02/2adcaa145158bf1a8295d83591d22e4103dbfd821bcaf6f3f53151ca4ffa/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea0cb07ebda26bb9b29ba82cda34849e73c166c18162d3913575b0c9db9a6182", size = 10248621, upload-time = "2025-03-07T01:40:21.213Z" }, ] -[[package]] -name = "nvidia-cuda-nvcc-cu12" -version = "12.9.86" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/25/48/b54a06168a2190572a312bfe4ce443687773eb61367ced31e064953dd2f7/nvidia_cuda_nvcc_cu12-12.9.86-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:5d6a0d32fdc7ea39917c20065614ae93add6f577d840233237ff08e9a38f58f0", size = 40546229, upload-time = "2025-06-05T20:01:53.357Z" }, - { url = "https://files.pythonhosted.org/packages/d6/5c/8cc072436787104bbbcbde1f76ab4a0d89e68f7cebc758dd2ad7913a43d0/nvidia_cuda_nvcc_cu12-12.9.86-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:44e1eca4d08926193a558d2434b1bf83d57b4d5743e0c431c0c83d51da1df62b", size = 39411138, upload-time = "2025-06-05T20:01:43.182Z" }, -] - [[package]] name = "nvidia-cuda-nvrtc-cu12" version = "12.8.93" source = { registry = "https://pypi.org/simple" } wheels = [ { url = "https://files.pythonhosted.org/packages/05/6b/32f747947df2da6994e999492ab306a903659555dddc0fbdeb9d71f75e52/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994", size = 88040029, upload-time = "2025-03-07T01:42:13.562Z" }, - { url = "https://files.pythonhosted.org/packages/eb/d1/e50d0acaab360482034b84b6e27ee83c6738f7d32182b987f9c7a4e32962/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fc1fec1e1637854b4c0a65fb9a8346b51dd9ee69e61ebaccc82058441f15bce8", size = 43106076, upload-time = "2025-03-07T01:41:59.817Z" }, ] [[package]] @@ -1890,7 +1825,6 @@ name = "nvidia-cuda-runtime-cu12" version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/75/f865a3b236e4647605ea34cc450900854ba123834a5f1598e160b9530c3a/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:52bf7bbee900262ffefe5e9d5a2a69a30d97e2bc5bb6cc866688caa976966e3d", size = 965265, upload-time = "2025-03-07T01:39:43.533Z" }, { url = "https://files.pythonhosted.org/packages/0d/9b/a997b638fcd068ad6e4d53b8551a7d30fe8b404d6f1804abf1df69838932/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90", size = 954765, upload-time = "2025-03-07T01:40:01.615Z" }, ] @@ -1902,7 +1836,6 @@ dependencies = [ { name = "nvidia-cublas-cu12" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/41/e79269ce215c857c935fd86bcfe91a451a584dfc27f1e068f568b9ad1ab7/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:c9132cc3f8958447b4910a1720036d9eff5928cc3179b0a51fb6d167c6cc87d8", size = 705026878, upload-time = "2025-06-06T21:52:51.348Z" }, { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, ] @@ -1914,7 +1847,6 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/60/bc/7771846d3a0272026c416fbb7e5f4c1f146d6d80704534d0b187dd6f4800/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:848ef7224d6305cdb2a4df928759dca7b1201874787083b6e7550dd6765ce69a", size = 193109211, upload-time = "2025-03-07T01:44:56.873Z" }, { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, ] @@ -1944,7 +1876,6 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/32/f7cd6ce8a7690544d084ea21c26e910a97e077c9b7f07bf5de623ee19981/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:db9ed69dbef9715071232caa9b69c52ac7de3a95773c2db65bdba85916e4e5c0", size = 267229841, upload-time = "2025-03-07T01:46:54.356Z" }, { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, ] @@ -1956,7 +1887,6 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/f7/cd777c4109681367721b00a106f491e0d0d15cfa1fd59672ce580ce42a97/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9b6c161cb130be1a07a27ea6923df8141f3c295852f4b260c65f18f3e0a091dc", size = 288117129, upload-time = "2025-03-07T01:47:40.407Z" }, { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, ] @@ -1973,7 +1903,6 @@ name = "nvidia-nccl-cu12" version = "2.27.3" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/7b/8354b784cf73b0ba51e566b4baba3ddd44fe8288a3d39ef1e06cd5417226/nvidia_nccl_cu12-2.27.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9ddf1a245abc36c550870f26d537a9b6087fb2e2e3d6e0ef03374c6fd19d984f", size = 322397768, upload-time = "2025-06-03T21:57:30.234Z" }, { url = "https://files.pythonhosted.org/packages/5c/5b/4e4fff7bad39adf89f735f2bc87248c81db71205b62bcc0d5ca5b606b3c3/nvidia_nccl_cu12-2.27.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adf27ccf4238253e0b826bce3ff5fa532d65fc42322c8bfdfaf28024c0fbe039", size = 322364134, upload-time = "2025-06-03T21:58:04.013Z" }, ] @@ -1983,16 +1912,6 @@ version = "12.8.93" source = { registry = "https://pypi.org/simple" } wheels = [ { url = "https://files.pythonhosted.org/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88", size = 39254836, upload-time = "2025-03-07T01:49:55.661Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a2/8cee5da30d13430e87bf99bb33455d2724d0a4a9cb5d7926d80ccb96d008/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:adccd7161ace7261e01bb91e44e88da350895c270d23f744f0820c818b7229e7", size = 38386204, upload-time = "2025-03-07T01:49:43.612Z" }, -] - -[[package]] -name = "nvidia-nvshmem-cu12" -version = "3.4.5" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/6a/03aa43cc9bd3ad91553a88b5f6fb25ed6a3752ae86ce2180221962bc2aa5/nvidia_nvshmem_cu12-3.4.5-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0b48363fc6964dede448029434c6abed6c5e37f823cb43c3bcde7ecfc0457e15", size = 138936938, upload-time = "2025-09-06T00:32:05.589Z" }, - { url = "https://files.pythonhosted.org/packages/b5/09/6ea3ea725f82e1e76684f0708bbedd871fc96da89945adeba65c3835a64c/nvidia_nvshmem_cu12-3.4.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:042f2500f24c021db8a06c5eec2539027d57460e1c1a762055a6554f72c369bd", size = 139103095, upload-time = "2025-09-06T00:32:31.266Z" }, ] [[package]]