diff --git a/artist/field/actuator.py b/artist/field/actuator.py index ef323daa..2bb53545 100644 --- a/artist/field/actuator.py +++ b/artist/field/actuator.py @@ -1,3 +1,5 @@ +from typing import Union + import torch @@ -81,7 +83,7 @@ def __init__( self.phi_0 = phi_0 def motor_steps_to_angles( - self, motor_steps: torch.Tensor, device: torch.device = "cpu" + self, motor_steps: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Translate motor steps to a joint angle. @@ -90,6 +92,8 @@ def motor_steps_to_angles( ---------- motor_steps : torch.Tensor The motor steps. + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Raises ------ @@ -99,7 +103,7 @@ def motor_steps_to_angles( raise NotImplementedError("Must be overridden!") def angles_to_motor_steps( - self, angles: torch.Tensor, device: torch.device = "cpu" + self, angles: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Translate a joint angle to motor steps. @@ -108,6 +112,8 @@ def angles_to_motor_steps( ---------- angles : torch.Tensor The joint angles. + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Raises ------ @@ -116,7 +122,9 @@ def angles_to_motor_steps( """ raise NotImplementedError("Must be overridden!") - def forward(self, actuator_pos: torch.Tensor) -> torch.Tensor: + def forward( + self, actuator_pos: torch.Tensor, device: Union[torch.device, str] = "cuda" + ) -> torch.Tensor: """ Perform forward kinematic. @@ -124,6 +132,8 @@ def forward(self, actuator_pos: torch.Tensor) -> torch.Tensor: ---------- actuator_pos : torch.Tensor The position of the actuator. + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Raises ------ diff --git a/artist/field/actuator_array.py b/artist/field/actuator_array.py index 54789cec..5bb33cc7 100644 --- a/artist/field/actuator_array.py +++ b/artist/field/actuator_array.py @@ -1,4 +1,5 @@ import logging +from typing import Union import torch @@ -30,7 +31,7 @@ class ActuatorArray(torch.nn.Module): def __init__( self, actuator_list_config: ActuatorListConfig, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> None: """ Initialize the actuator array. @@ -44,10 +45,11 @@ def __init__( ---------- actuator_list_config : ActuatorListConfig The configuration parameters for the actuators. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). """ super().__init__() + device = torch.device(device) actuator_array = [] # Iterate through each actuator configuration in the list of actuator configurations. for i, actuator_config in enumerate(actuator_list_config.actuator_list): diff --git a/artist/field/actuator_ideal.py b/artist/field/actuator_ideal.py index ebaf40a8..d9c5c5cb 100644 --- a/artist/field/actuator_ideal.py +++ b/artist/field/actuator_ideal.py @@ -1,3 +1,5 @@ +from typing import Union + import torch from artist.field.actuator import ( @@ -24,7 +26,7 @@ class IdealActuator(Actuator): """ def motor_steps_to_angles( - self, motor_steps: torch.Tensor, device: torch.device = "cpu" + self, motor_steps: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Translate motor steps to a joint angle. @@ -33,8 +35,8 @@ def motor_steps_to_angles( ---------- motor_steps : torch.Tensor The motor steps. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -44,7 +46,7 @@ def motor_steps_to_angles( return motor_steps def angles_to_motor_steps( - self, angles: torch.Tensor, device: torch.device = "cpu" + self, angles: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Translate a joint angle to motor steps. @@ -53,8 +55,8 @@ def angles_to_motor_steps( ---------- angles : torch.Tensor The joint angles. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -64,7 +66,7 @@ def angles_to_motor_steps( return angles def forward( - self, actuator_pos: torch.Tensor, device: torch.device = "cpu" + self, actuator_pos: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Perform the forward kinematic for an ideal actuator. @@ -73,8 +75,8 @@ def forward( ---------- actuator_pos : torch.Tensor The position of the actuator. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- diff --git a/artist/field/actuator_linear.py b/artist/field/actuator_linear.py index e5fb24a9..966beac3 100644 --- a/artist/field/actuator_linear.py +++ b/artist/field/actuator_linear.py @@ -1,3 +1,5 @@ +from typing import Union + import torch from artist.field.actuator import Actuator @@ -120,7 +122,7 @@ def steps_to_phi(self, actuator_pos: torch.Tensor) -> torch.Tensor: return angle def motor_steps_to_angles( - self, actuator_pos: torch.Tensor, device: torch.device = "cpu" + self, actuator_pos: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Calculate the angles given the motor steps. @@ -129,14 +131,15 @@ def motor_steps_to_angles( ---------- actuator_pos : torch.Tensor The actuator (motor) position. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor The angles corresponding to the motor steps. """ + device = torch.device(device) phi = self.steps_to_phi(actuator_pos=actuator_pos) phi_0 = self.steps_to_phi( actuator_pos=torch.zeros(actuator_pos.shape, device=device) @@ -147,7 +150,7 @@ def motor_steps_to_angles( return angles def angles_to_motor_steps( - self, angles: torch.Tensor, device: torch.device = "cpu" + self, angles: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Calculate the motor steps given the angles. @@ -156,14 +159,15 @@ def angles_to_motor_steps( ---------- angles : torch.Tensor The angles. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor The motor steps. """ + device = torch.device(device) delta_phi = angles - self.phi_0 if self.clockwise else self.phi_0 - angles phi_0 = self.steps_to_phi( @@ -179,7 +183,7 @@ def angles_to_motor_steps( return actuator_steps def forward( - self, actuator_pos: torch.Tensor, device: torch.device = "cpu" + self, actuator_pos: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Perform the forward kinematic. @@ -188,12 +192,14 @@ def forward( ---------- actuator_pos : torch.Tensor The actuator (motor) position. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor The angles. """ - return self.motor_steps_to_angles(actuator_pos=actuator_pos, device=device) + return self.motor_steps_to_angles( + actuator_pos=actuator_pos, device=torch.device(device) + ) diff --git a/artist/field/facets_nurbs.py b/artist/field/facets_nurbs.py index f8f9de63..b155f160 100644 --- a/artist/field/facets_nurbs.py +++ b/artist/field/facets_nurbs.py @@ -1,3 +1,5 @@ +from typing import Union + import torch from artist.util.nurbs import NURBSSurface @@ -90,20 +92,23 @@ def __init__( self.canting_e = canting_e self.canting_n = canting_n - def create_nurbs_surface(self, device: torch.device = "cpu") -> NURBSSurface: + def create_nurbs_surface( + self, device: Union[torch.device, str] = "cuda" + ) -> NURBSSurface: """ Create a NURBS surface to model a facet. Parameters ---------- - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- NURBSSurface The NURBS surface of one facet. """ + device = torch.device(device) # Since NURBS are only defined between (0,1), a small offset is required to exclude the boundaries from the # defined evaluation points. evaluation_points_rows = torch.linspace( diff --git a/artist/field/heliostat.py b/artist/field/heliostat.py index 33658ffe..f4e91863 100644 --- a/artist/field/heliostat.py +++ b/artist/field/heliostat.py @@ -1,5 +1,5 @@ import logging -from typing import Optional +from typing import Optional, Union import h5py import torch @@ -70,7 +70,7 @@ def __init__( surface_config: SurfaceConfig, kinematic_config: KinematicLoadConfig, actuator_config: ActuatorListConfig, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> None: """ Implement the behavior of a heliostat. @@ -95,10 +95,11 @@ def __init__( The configuration parameters to use for the heliostat kinematic. actuator_config : ActuatorListConfig The configuration parameters to use for the list of actuators. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). """ super().__init__() + device = torch.device(device) self.heliostat_id = heliostat_id self.position = position self.aim_point = aim_point @@ -130,7 +131,7 @@ def from_hdf5( prototype_kinematic: Optional[KinematicLoadConfig] = None, prototype_actuator: Optional[ActuatorListConfig] = None, heliostat_name: Optional[str] = None, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> Self: """ Class method to initialize a heliostat from an HDF5 file. @@ -147,8 +148,8 @@ def from_hdf5( An optional prototype for the actuator configuration. heliostat_name : str, optional The name of the heliostat being loaded - used for logging. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -157,6 +158,7 @@ def from_hdf5( """ if heliostat_name: log.info(f"Loading {heliostat_name} from an HDF5 file.") + device = torch.device(device) heliostat_id = int(config_file[config_dictionary.heliostat_id][()]) position = torch.tensor( config_file[config_dictionary.heliostat_position][()], @@ -752,7 +754,9 @@ def from_hdf5( ) def set_aligned_surface( - self, incident_ray_direction: torch.Tensor, device: torch.device = "cpu" + self, + incident_ray_direction: torch.Tensor, + device: Union[torch.device, str] = "cuda", ) -> None: """ Compute the aligned surface points and aligned surface normals of the heliostat. @@ -761,9 +765,11 @@ def set_aligned_surface( ---------- incident_ray_direction : torch.Tensor The incident ray direction. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). """ + device = torch.device(device) + surface_points, surface_normals = self.surface.get_surface_points_and_normals( device=device ) diff --git a/artist/field/heliostat_field.py b/artist/field/heliostat_field.py index c738a50e..7bcf6d8c 100644 --- a/artist/field/heliostat_field.py +++ b/artist/field/heliostat_field.py @@ -1,4 +1,5 @@ import logging +from typing import Union import h5py import torch.nn @@ -54,7 +55,7 @@ def from_hdf5( prototype_surface: SurfaceConfig, prototype_kinematic: KinematicLoadConfig, prototype_actuator: ActuatorListConfig, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> Self: """ Load a heliostat field from an HDF5 file. @@ -69,8 +70,8 @@ def from_hdf5( The prototype for the kinematic configuration to be used if the heliostat has no individual kinematic. prototype_actuator : ActuatorListConfig The prototype for the actuator configuration to be used if the heliostat has no individual actuators. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -78,6 +79,7 @@ def from_hdf5( The heliostat field loaded from the HDF5 file. """ log.info("Loading a heliostat field from an HDF5 file.") + device = torch.device(device) heliostat_list = [ Heliostat.from_hdf5( config_file=config_file[config_dictionary.heliostat_key][ diff --git a/artist/field/kinematic_rigid_body.py b/artist/field/kinematic_rigid_body.py index 1011c1f1..ec6a80fa 100644 --- a/artist/field/kinematic_rigid_body.py +++ b/artist/field/kinematic_rigid_body.py @@ -1,3 +1,5 @@ +from typing import Union + import torch from artist.field.actuator_array import ActuatorArray @@ -67,7 +69,7 @@ def __init__( concentrator_tilt_n=torch.tensor(0.0), concentrator_tilt_u=torch.tensor(0.0), ), - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> None: """ Initialize the rigid body kinematic. @@ -89,11 +91,11 @@ def __init__( The initial orientation offsets of the kinematic (default: 0.0 for each possible offset). deviation_parameters : KinematicDeviations The deviation parameters for the kinematic (default: 0.0 for each deviation). - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). """ super().__init__(position=position, aim_point=aim_point) - + device = torch.device(device) self.deviation_parameters = deviation_parameters for attr_name, attr_value in self.deviation_parameters.__dict__.items(): if isinstance(attr_value, torch.Tensor): @@ -115,7 +117,7 @@ def align( incident_ray_direction: torch.Tensor, max_num_iterations: int = 2, min_eps: float = 0.0001, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> torch.Tensor: """ Compute the rotation matrix to align the heliostat along a desired orientation. @@ -128,8 +130,8 @@ def align( Maximum number of iterations (default: 2). min_eps : float Convergence criterion (default: 0.0001). - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -139,7 +141,7 @@ def align( assert ( len(self.actuators.actuator_list) == 2 ), "The rigid body kinematic requires exactly two actuators, please check the configuration!" - + device = torch.device(device) actuator_steps = torch.zeros((1, 2), requires_grad=True, device=device) orientation = None last_iteration_loss = None @@ -315,7 +317,7 @@ def align_surface( incident_ray_direction: torch.Tensor, surface_points: torch.Tensor, surface_normals: torch.Tensor, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> tuple[torch.Tensor, torch.Tensor]: """ Align given surface points and surface normals according to a calculated orientation. @@ -328,8 +330,8 @@ def align_surface( Points on the surface of the heliostat that reflect the light. surface_normals : torch.Tensor Normals to the surface points. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -338,6 +340,8 @@ def align_surface( torch.Tensor The aligned surface normals. """ + device = torch.device(device) + orientation = self.align(incident_ray_direction, device=device).squeeze() aligned_surface_points = (orientation @ surface_points.unsqueeze(-1)).squeeze( diff --git a/artist/field/receiver.py b/artist/field/receiver.py index 4774d79e..1cd64a4e 100644 --- a/artist/field/receiver.py +++ b/artist/field/receiver.py @@ -1,5 +1,5 @@ import logging -from typing import Optional +from typing import Optional, Union import h5py import torch.nn @@ -97,7 +97,7 @@ def from_hdf5( cls, config_file: h5py.File, receiver_name: Optional[str] = None, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> Self: """ Class method that initializes a receiver from an HDF5 file. @@ -108,8 +108,8 @@ def from_hdf5( The HDF5 file containing the information about the receiver. receiver_name : str, optional The name of the receiver - used for logging - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -118,6 +118,7 @@ def from_hdf5( """ if receiver_name: log.info(f"Loading {receiver_name} from an HDF5 file.") + device = torch.device(device) receiver_type = config_file[config_dictionary.receiver_type][()].decode("utf-8") position_center = torch.tensor( config_file[config_dictionary.receiver_position_center][()], diff --git a/artist/field/receiver_field.py b/artist/field/receiver_field.py index bc5de819..1fda479a 100644 --- a/artist/field/receiver_field.py +++ b/artist/field/receiver_field.py @@ -1,4 +1,5 @@ import logging +from typing import Union import h5py import torch.nn @@ -42,7 +43,9 @@ def __init__(self, receiver_list: list[Receiver]): self.receiver_list = receiver_list @classmethod - def from_hdf5(cls, config_file: h5py.File, device: torch.device = "cpu") -> Self: + def from_hdf5( + cls, config_file: h5py.File, device: Union[torch.device, str] = "cuda" + ) -> Self: """ Load a receiver field from an HDF5 file. @@ -50,8 +53,8 @@ def from_hdf5(cls, config_file: h5py.File, device: torch.device = "cpu") -> Self ---------- config_file : h5py.File The HDF5 file containing the configuration to be loaded. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -59,6 +62,7 @@ def from_hdf5(cls, config_file: h5py.File, device: torch.device = "cpu") -> Self The receiver field loaded from the HDF5 file. """ log.info("Loading a receiver field from an HDF5 file.") + device = torch.device(device) receiver_field = [ Receiver.from_hdf5( config_file=config_file[config_dictionary.receiver_key][receiver_name], diff --git a/artist/field/surface.py b/artist/field/surface.py index 1adfb5d0..e43204ba 100644 --- a/artist/field/surface.py +++ b/artist/field/surface.py @@ -1,3 +1,5 @@ +from typing import Union + import torch from artist.field.facets_nurbs import NurbsFacet @@ -51,15 +53,15 @@ def __init__(self, surface_config: SurfaceConfig) -> None: ] def get_surface_points_and_normals( - self, device: torch.device = "cpu" + self, device: Union[torch.device, str] = "cuda" ) -> tuple[torch.Tensor, torch.Tensor]: """ Calculate all surface points and normals from all facets. Parameters ---------- - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -68,6 +70,7 @@ def get_surface_points_and_normals( torch.Tensor The surface normals. """ + device = torch.device(device) eval_point_per_facet = ( self.facets[0].number_eval_points_n * self.facets[0].number_eval_points_e ) diff --git a/artist/raytracing/heliostat_tracing.py b/artist/raytracing/heliostat_tracing.py index 19d52580..c6e9faf0 100644 --- a/artist/raytracing/heliostat_tracing.py +++ b/artist/raytracing/heliostat_tracing.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Union if TYPE_CHECKING: from artist.scenario import Scenario @@ -190,7 +190,9 @@ def __init__( ) def trace_rays( - self, incident_ray_direction: torch.Tensor, device: torch.device = "cpu" + self, + incident_ray_direction: torch.Tensor, + device: Union[torch.device, str] = "cuda", ) -> torch.Tensor: """ Perform heliostat raytracing. @@ -202,14 +204,15 @@ def trace_rays( ---------- incident_ray_direction : torch.Tensor The direction of the incident ray as seen from the heliostat. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor The resulting bitmap. """ + device = torch.device(device) final_bitmap = torch.zeros( (self.receiver.resolution_e, self.receiver.resolution_u), device=device ) @@ -254,7 +257,7 @@ def scatter_rays( self, distortion_u: torch.Tensor, distortion_e: torch.Tensor, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> Rays: """ Scatter the reflected rays around the preferred ray direction. @@ -265,14 +268,15 @@ def scatter_rays( The distortions in up direction (angles for scattering). distortion_e : torch.Tensor The distortions in east direction (angles for scattering). - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- Rays Scattered rays around the preferred direction. """ + device = torch.device(device) ray_directions = self.heliostat.preferred_reflection_direction[ :, :, :3 ] / torch.linalg.norm( @@ -308,7 +312,7 @@ def sample_bitmap( dx_ints: torch.Tensor, dy_ints: torch.Tensor, indices: torch.Tensor, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> torch.Tensor: """ Sample a bitmap (flux density distribution of the reflected rays on the receiver). @@ -323,14 +327,16 @@ def sample_bitmap( the y-axis. indices : torch.Tensor Index of the pixel. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor The flux density distribution of the reflected rays on the receiver. """ + device = torch.device(device) + x_ints = dx_ints[indices] / self.receiver.plane_e * self.receiver.resolution_e y_ints = dy_ints[indices] / self.receiver.plane_u * self.receiver.resolution_u diff --git a/artist/scenario.py b/artist/scenario.py index 515bbf86..55258afa 100644 --- a/artist/scenario.py +++ b/artist/scenario.py @@ -1,4 +1,5 @@ import logging +from typing import Union import h5py import torch @@ -71,7 +72,7 @@ def __init__( @classmethod def load_scenario_from_hdf5( - cls, scenario_file: h5py.File, device: torch.device = "cpu" + cls, scenario_file: h5py.File, device: Union[torch.device, str] = "cuda" ) -> Self: """ Class method to load the scenario from an HDF5 file. @@ -80,8 +81,8 @@ def load_scenario_from_hdf5( ---------- scenario_file : h5py.File The config file containing all the information about the scenario being loaded. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -91,6 +92,7 @@ def load_scenario_from_hdf5( log.info( f"Loading an ``ARTIST`` scenario HDF5 file. This scenario file is version {scenario_file.attrs['version']}." ) + device = torch.device(device) receivers = ReceiverField.from_hdf5(config_file=scenario_file, device=device) light_sources = LightSourceArray.from_hdf5( config_file=scenario_file, device=device diff --git a/artist/scene/light_source_array.py b/artist/scene/light_source_array.py index dc5080f3..8ae0ce32 100644 --- a/artist/scene/light_source_array.py +++ b/artist/scene/light_source_array.py @@ -1,4 +1,5 @@ import logging +from typing import Union import h5py import torch.nn @@ -47,7 +48,9 @@ def __init__(self, light_source_list: list[LightSource]): self.light_source_list = light_source_list @classmethod - def from_hdf5(cls, config_file: h5py.File, device: torch.device = "cpu") -> Self: + def from_hdf5( + cls, config_file: h5py.File, device: Union[torch.device, str] = "cuda" + ) -> Self: """ Load a light source array from an HDF5 file. @@ -55,8 +58,8 @@ def from_hdf5(cls, config_file: h5py.File, device: torch.device = "cpu") -> Self ---------- config_file : h5py.File The HDF5 file containing the configuration to be loaded. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -64,6 +67,7 @@ def from_hdf5(cls, config_file: h5py.File, device: torch.device = "cpu") -> Self The light source array loaded from the HDF5 file. """ log.info("Loading a light source array from an HDF5 file.") + device = torch.device(device) light_source_array = [] # Iterate through each light source configuration in the list of light source configurations. for ls in config_file[config_dictionary.light_source_key].keys(): diff --git a/artist/scene/sun.py b/artist/scene/sun.py index ea25f427..648085c2 100644 --- a/artist/scene/sun.py +++ b/artist/scene/sun.py @@ -1,5 +1,5 @@ import logging -from typing import Any, Optional +from typing import Any, Optional, Union import h5py import torch @@ -41,7 +41,7 @@ def __init__( distribution_parameters: dict[str, Any] = dict( distribution_type="normal", mean=0.0, covariance=4.3681e-06 ), - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> None: """ Initialize the sun as a light source. @@ -57,8 +57,8 @@ def __init__( The number of sent-out rays sampled from the sun distribution. distribution_parameters Parameters of the distribution used to model the sun. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Raises ------ @@ -66,6 +66,7 @@ def __init__( If the specified distribution type is unknown. """ super().__init__(number_of_rays=number_of_rays) + device = torch.device(device) self.distribution_parameters = distribution_parameters self.number_of_rays = number_of_rays @@ -120,7 +121,7 @@ def from_hdf5( cls, config_file: h5py.File, light_source_name: Optional[str] = None, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> Self: """ Class method that initializes a sun from an HDF5 file. @@ -131,8 +132,8 @@ def from_hdf5( The HDF5 file containing the information about the sun. light_source_name : str, optional The name of the light source - used for logging. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -141,6 +142,8 @@ def from_hdf5( """ if light_source_name: log.info(f"Loading {light_source_name} from an HDF5 file.") + device = torch.device(device) + number_of_rays = int( config_file[config_dictionary.light_source_number_of_rays][()] ) diff --git a/artist/util/nurbs.py b/artist/util/nurbs.py index ae0cccf5..393ed84b 100644 --- a/artist/util/nurbs.py +++ b/artist/util/nurbs.py @@ -1,3 +1,5 @@ +from typing import Union + import torch @@ -41,7 +43,7 @@ def __init__( evaluation_points_e: torch.Tensor, evaluation_points_n: torch.Tensor, control_points: torch.Tensor, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> None: """ Initialize a NURBS surface. @@ -63,10 +65,11 @@ def __init__( The evaluation points in north direction. control_points : torch.Tensor The control_points. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). """ super().__init__() + device = torch.device(device) self.degree_e = degree_e self.degree_n = degree_n self.evaluation_points_e = evaluation_points_e @@ -75,7 +78,7 @@ def __init__( self.knot_vector_e, self.knot_vector_n = self.calculate_knots(device) def calculate_knots( - self, device: torch.device = "cpu" + self, device: Union[torch.device, str] = "cuda" ) -> tuple[torch.Tensor, torch.Tensor]: """ Calculate the knot vectors in the east and north direction. @@ -88,8 +91,8 @@ def calculate_knots( Parameters ---------- - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -98,6 +101,8 @@ def calculate_knots( torch.Tensor The knots in north direction. """ + device = torch.device(device) + num_control_points_e = self.control_points.shape[0] num_control_points_n = self.control_points.shape[1] @@ -123,7 +128,7 @@ def find_span( evaluation_points: torch.Tensor, knot_vector: torch.Tensor, control_points: torch.Tensor, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> torch.Tensor: """ Determine the knot span index for given evaluation points. @@ -143,14 +148,15 @@ def find_span( The knot vector for the NURBS surface in a single direction. control_points : torch.Tensor The control points. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor The knot span index. """ + device = torch.device(device) n = control_points.shape[1] - 1 span_indices = torch.zeros( len(evaluation_points), dtype=torch.int64, device=device @@ -182,7 +188,7 @@ def basis_function_and_derivatives( span: torch.Tensor, degree: int, nth_derivative: int = 1, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> torch.Tensor: """ Compute the nonzero derivatives of the basis functions up to the nth-derivative. @@ -201,14 +207,16 @@ def basis_function_and_derivatives( The degree of the NURBS surface in one direction. nth_derivative : int Specifies how many derivatives are calculated (default: 1). - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor The derivatives of the basis function. """ + device = torch.device(device) + num_evaluation_points = len(evaluation_points) # Introduce `ndu` to store the basis functions (called "n" in The NURBS book) and the knot differences (du). @@ -292,15 +300,15 @@ def basis_function_and_derivatives( return derivatives def calculate_surface_points_and_normals( - self, device: torch.device = "cpu" + self, device: Union[torch.device, str] = "cuda" ) -> tuple[torch.Tensor, torch.Tensor]: """ Calculate the surface points and normals of the NURBS surface. Parameters ---------- - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -309,6 +317,8 @@ def calculate_surface_points_and_normals( torch.Tensor The surface normals. """ + device = torch.device(device) + nth_derivative = 1 # Find span indices x direction (based on A2.1, p. 68). diff --git a/artist/util/stral_to_surface_converter.py b/artist/util/stral_to_surface_converter.py index 13f79351..28d8d7f4 100644 --- a/artist/util/stral_to_surface_converter.py +++ b/artist/util/stral_to_surface_converter.py @@ -2,6 +2,7 @@ import struct import sys from pathlib import Path +from typing import Union import colorlog import torch @@ -105,7 +106,7 @@ def __init__( @staticmethod def convert_3d_points_to_4d_format( - point: torch.Tensor, device: torch.device = "cpu" + point: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Append ones to the last dimension of a 3D point vector. @@ -116,14 +117,15 @@ def convert_3d_points_to_4d_format( ---------- point : torch.Tensor Input point in a 3D format. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor Point vector with ones appended at the last dimension. """ + device = torch.device(device) assert ( point.size(dim=-1) == 3 ), f"Expected a 3D point but got a point of shape {point.shape}!" @@ -134,7 +136,7 @@ def convert_3d_points_to_4d_format( @staticmethod def convert_3d_direction_to_4d_format( - direction: torch.Tensor, device: torch.device = "cpu" + direction: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Append zeros to the last dimension of a 3D direction vector. @@ -145,14 +147,15 @@ def convert_3d_direction_to_4d_format( ---------- direction : torch.Tensor Input direction in a 3D format. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor Direction vector with ones appended at the last dimension. """ + device = torch.device(device) assert ( direction.size(dim=-1) == 3 ), f"Expected a 3D direction vector but got a director vector of shape {direction.shape}!" @@ -163,7 +166,7 @@ def convert_3d_direction_to_4d_format( @staticmethod def nwu_to_enu( - nwu_tensor: torch.Tensor, device: torch.device = "cpu" + nwu_tensor: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Cast the coordinate system from NWU to ENU. @@ -172,14 +175,15 @@ def nwu_to_enu( ---------- nwu_tensor : torch.Tensor The tensor in the NWU coordinate system. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor The converted tensor in the ENU coordinate system. """ + device = torch.device(device) return torch.tensor( [-nwu_tensor[1], nwu_tensor[0], nwu_tensor[2]], dtype=torch.float, @@ -223,7 +227,7 @@ def fit_nurbs_surface( tolerance: float = 1e-5, initial_learning_rate: float = 1e-1, max_epoch: int = 2500, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> NURBSSurface: """ Generate a NURBS surface based on ``STRAL`` data. @@ -256,14 +260,16 @@ def fit_nurbs_surface( Initial learning rate for the learning rate scheduler (default: 1e-1). max_epoch : int, optional Maximum number of epochs for optimization (default: 2500). - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- NURBSSurface A NURBS surface. """ + device = torch.device(device) + # Normalize evaluation points and shift them so that they correspond to the knots. evaluation_points = surface_points.clone() evaluation_points[:, 2] = 0 @@ -365,7 +371,7 @@ def generate_surface_config_from_stral( tolerance: float = 1e-5, initial_learning_rate: float = 1e-1, max_epoch: int = 10000, - device: torch.device = "cpu", + device: Union[torch.device, str] = "cuda", ) -> list[FacetConfig]: """ Generate a surface configuration from a ``STRAL`` file. @@ -392,8 +398,8 @@ def generate_surface_config_from_stral( Initial learning rate for the learning rate scheduler used when fitting NURBS surfaces (default: 1e-1). max_epoch : int Maximum number of epochs to use when fitting NURBS surfaces (default: 10000). - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -403,6 +409,7 @@ def generate_surface_config_from_stral( log.info( "Beginning generation of the surface configuration based on STRAL data." ) + device = torch.device(device) # Create structures for reading ``STRAL`` file correctly. surface_header_struct = struct.Struct(self.surface_header_name) diff --git a/artist/util/utils.py b/artist/util/utils.py index 90818e3a..a68446f6 100644 --- a/artist/util/utils.py +++ b/artist/util/utils.py @@ -1,3 +1,5 @@ +from typing import Union + import torch @@ -22,7 +24,7 @@ def batch_dot(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor: def rotate_distortions( - e: torch.Tensor, u: torch.Tensor, device: torch.device = "cpu" + e: torch.Tensor, u: torch.Tensor, device: Union[torch.device, str] = "cuda" ) -> torch.Tensor: """ Rotate the distortions for the sun. @@ -39,8 +41,8 @@ def rotate_distortions( East rotation angle in radians. u : torch.Tensor Up rotation angle in radians. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -50,6 +52,7 @@ def rotate_distortions( assert ( e.shape == u.shape ), "The two tensors containing angles for the east and up rotation must have the same shape." + device = torch.device(device) cos_e = torch.cos(e) sin_e = -torch.sin(e) # Heliostat convention @@ -69,7 +72,9 @@ def rotate_distortions( ).permute(0, 3, 4, 1, 2) -def rotate_e(e: torch.Tensor, device: torch.device = "cpu") -> torch.Tensor: +def rotate_e( + e: torch.Tensor, device: Union[torch.device, str] = "cuda" +) -> torch.Tensor: """ Rotate around the east axis. @@ -82,14 +87,16 @@ def rotate_e(e: torch.Tensor, device: torch.device = "cpu") -> torch.Tensor: ---------- e : torch.Tensor East rotation angle in radians. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor Corresponding rotation matrix. """ + device = torch.device(device) + cos_e = torch.cos(e) sin_e = -torch.sin(e) # Heliostat convention zeros = torch.zeros(e.shape, device=device) @@ -104,7 +111,9 @@ def rotate_e(e: torch.Tensor, device: torch.device = "cpu") -> torch.Tensor: ).squeeze(-1) -def rotate_n(n: torch.Tensor, device: torch.device = "cpu") -> torch.Tensor: +def rotate_n( + n: torch.Tensor, device: Union[torch.device, str] = "cuda" +) -> torch.Tensor: """ Rotate around the north axis. @@ -116,14 +125,16 @@ def rotate_n(n: torch.Tensor, device: torch.device = "cpu") -> torch.Tensor: ---------- n : torch.Tensor North rotation angle in radians. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor Corresponding rotation matrix. """ + device = torch.device(device) + cos_n = torch.cos(n) sin_n = torch.sin(n) zeros = torch.zeros(n.shape, device=device) @@ -139,7 +150,9 @@ def rotate_n(n: torch.Tensor, device: torch.device = "cpu") -> torch.Tensor: ).squeeze(-1) -def rotate_u(u: torch.Tensor, device: torch.device = "cpu") -> torch.Tensor: +def rotate_u( + u: torch.Tensor, device: Union[torch.device, str] = "cuda" +) -> torch.Tensor: """ Rotate around the up axis. @@ -151,14 +164,16 @@ def rotate_u(u: torch.Tensor, device: torch.device = "cpu") -> torch.Tensor: ---------- u : torch.Tensor Up rotation angle in radians. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- torch.Tensor Corresponding rotation matrix. """ + device = torch.device(device) + cos_u = torch.cos(u) sin_u = torch.sin(u) zeros = torch.zeros(u.shape, device=device) @@ -175,7 +190,10 @@ def rotate_u(u: torch.Tensor, device: torch.device = "cpu") -> torch.Tensor: def translate_enu( - e: torch.Tensor, n: torch.Tensor, u: torch.Tensor, device: torch.device = "cpu" + e: torch.Tensor, + n: torch.Tensor, + u: torch.Tensor, + device: Union[torch.device, str] = "cuda", ) -> torch.Tensor: """ Translate in all directions. @@ -191,8 +209,8 @@ def translate_enu( North translation. u : torch.Tensor Up translation. - device : torch.device - The device on which to initialize tensors (default is CPU). + device : Union[torch.device, str] + The device on which to initialize tensors (default is cuda). Returns ------- @@ -202,6 +220,7 @@ def translate_enu( assert ( e.shape == u.shape == n.shape ), "The three tensors containing the east, north, and up translations must have the same shape." + device = torch.device(device) zeros = torch.zeros(e.shape, device=device) ones = torch.ones(e.shape, device=device) diff --git a/scenarios/example_generate_individual_test_scenario.py b/scenarios/example_generate_individual_test_scenario.py index 5b3c950d..68dd2097 100644 --- a/scenarios/example_generate_individual_test_scenario.py +++ b/scenarios/example_generate_individual_test_scenario.py @@ -25,7 +25,7 @@ from artist.util.scenario_generator import ScenarioGenerator from artist.util.stral_to_surface_converter import StralToSurfaceConverter -device = torch.device("cuda:3" if torch.cuda.is_available() else "cpu") +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # The following parameter is the name of the scenario. file_path = "test_individual_measurements_scenario" diff --git a/scenarios/example_generate_multiple_heliostat_scenario.py b/scenarios/example_generate_multiple_heliostat_scenario.py index 6d8dab3d..931d02a7 100644 --- a/scenarios/example_generate_multiple_heliostat_scenario.py +++ b/scenarios/example_generate_multiple_heliostat_scenario.py @@ -22,7 +22,7 @@ ) from artist.util.scenario_generator import ScenarioGenerator -device = torch.device("cuda:3" if torch.cuda.is_available() else "cpu") +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # The following parameter is the name of the scenario. file_path = "multiple_heliostat_scenario" diff --git a/scenarios/example_generate_test_scenario.py b/scenarios/example_generate_test_scenario.py index 7075d813..58eedf7d 100644 --- a/scenarios/example_generate_test_scenario.py +++ b/scenarios/example_generate_test_scenario.py @@ -22,7 +22,7 @@ from artist.util.scenario_generator import ScenarioGenerator from artist.util.stral_to_surface_converter import StralToSurfaceConverter -device = torch.device("cuda:3" if torch.cuda.is_available() else "cpu") +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # The following parameter is the name of the scenario. file_path = "test_scenario" diff --git a/tests/field/test_integration_stral_data.py b/tests/field/test_integration_stral_data.py index b924b254..8229111e 100644 --- a/tests/field/test_integration_stral_data.py +++ b/tests/field/test_integration_stral_data.py @@ -33,9 +33,21 @@ rank = 0 -@pytest.fixture(params=["cpu", "cuda:3"] if torch.cuda.is_available() else ["cpu"]) +@pytest.fixture(params=["cpu", "cuda"] if torch.cuda.is_available() else ["cpu"]) def device(request: pytest.FixtureRequest) -> torch.device: - """Return the device on which to initialize tensors.""" + """ + Return the device on which to initialize tensors. + + Parameters + ---------- + request : pytest.FixtureRequest + The pytest fixture used to consider different test cases. + + Returns + ------- + torch.device + The device on which to initialize tensors. + """ return torch.device(request.param) @@ -78,6 +90,11 @@ def test_compute_bitmaps( The name of the scenario to be loaded. device : torch.device The device on which to initialize tensors. + + Raises + ------ + AssertionError + If test does not complete as expected. """ torch.manual_seed(7) torch.cuda.manual_seed(7) diff --git a/tests/field/test_linear_actuator.py b/tests/field/test_linear_actuator.py index f998e81d..97ebf77e 100644 --- a/tests/field/test_linear_actuator.py +++ b/tests/field/test_linear_actuator.py @@ -13,15 +13,39 @@ ) -@pytest.fixture(params=["cpu", "cuda:3"] if torch.cuda.is_available() else ["cpu"]) +@pytest.fixture(params=["cpu", "cuda"] if torch.cuda.is_available() else ["cpu"]) def device(request: pytest.FixtureRequest) -> torch.device: - """Return the device on which to initialize tensors.""" + """ + Return the device on which to initialize tensors. + + Parameters + ---------- + request : pytest.FixtureRequest + The pytest fixture used to consider different test cases. + + Returns + ------- + torch.device + The device on which to initialize tensors. + """ return torch.device(request.param) @pytest.fixture -def deviation_parameters(device: torch.device): - """Define deviation parameters used in tests.""" +def deviation_parameters(device: torch.device) -> KinematicDeviations: + """ + Define deviation parameters used in tests. + + Parameters + ---------- + device : torch.device + The device on which to initialize tensors. + + Returns + ------- + KinematicDeviations + The deviation parameters. + """ deviation_parameters = KinematicDeviations( first_joint_translation_e=torch.tensor(0.0, device=device), first_joint_translation_n=torch.tensor(0.0, device=device), @@ -46,8 +70,20 @@ def deviation_parameters(device: torch.device): @pytest.fixture -def actuator_configuration(device: torch.device): - """Define actuator parameters used in tests as measured experimentally.""" +def actuator_configuration(device: torch.device) -> ActuatorListConfig: + """ + Define actuator parameters used in tests as measured experimentally. + + Parameters + ---------- + device : torch.device + The device on which to initialize tensors. + + Returns + ------- + ActuatorListConfig + A List containing parameters for each actuator. + """ actuator1_parameters = ActuatorParameters( increment=torch.tensor(154166.666, device=device), initial_stroke_length=torch.tensor(0.075, device=device), @@ -84,7 +120,7 @@ def kinematic_model_1( actuator_configuration: ActuatorListConfig, deviation_parameters: KinematicDeviations, device: torch.device, -): +) -> RigidBody: """ Create a kinematic model to use in the test. @@ -96,6 +132,11 @@ def kinematic_model_1( The kinematic deviations. device : torch.device The device on which to initialize tensors. + + Returns + ------- + RigidBody + The kinematic model. """ position = torch.tensor([0.0, 0.0, 0.0, 1.0], device=device) aim_point = torch.tensor([0.0, -10.0, 0.0, 1.0], device=device) @@ -113,7 +154,7 @@ def kinematic_model_2( actuator_configuration: ActuatorListConfig, deviation_parameters: KinematicDeviations, device: torch.device, -): +) -> RigidBody: """ Create a kinematic model to use in the test. @@ -125,6 +166,11 @@ def kinematic_model_2( The kinematic deviations. device : torch.device The device on which to initialize tensors. + + Returns + ------- + RigidBody + The kinematic model. """ position = torch.tensor([0.0, 1.0, 0.0, 1.0], device=device) aim_point = torch.tensor([0.0, -9.0, 0.0, 1.0], device=device) @@ -220,7 +266,7 @@ def test_orientation_matrix( incident_ray_direction: torch.Tensor, expected: torch.Tensor, device: torch.device, -): +) -> None: """ Test that the alignment works as desired. @@ -236,6 +282,11 @@ def test_orientation_matrix( The expected orientation matrix. device : torch.device The device on which to initialize tensors. + + Raises + ------ + AssertionError + If test does not complete as expected. """ orientation_matrix = request.getfixturevalue(kinematic_model_fixture).align( incident_ray_direction.to(device), device=device diff --git a/tests/field/test_only_nurbs.py b/tests/field/test_only_nurbs.py index e45f06e6..313ccb15 100644 --- a/tests/field/test_only_nurbs.py +++ b/tests/field/test_only_nurbs.py @@ -4,9 +4,21 @@ from artist.util.nurbs import NURBSSurface -@pytest.fixture(params=["cpu", "cuda:3"] if torch.cuda.is_available() else ["cpu"]) +@pytest.fixture(params=["cpu", "cuda"] if torch.cuda.is_available() else ["cpu"]) def device(request: pytest.FixtureRequest) -> torch.device: - """Return the device on which to initialize tensors.""" + """ + Return the device on which to initialize tensors. + + Parameters + ---------- + request : pytest.FixtureRequest + The pytest fixture used to consider different test cases. + + Returns + ------- + torch.device + The device on which to initialize tensors. + """ return torch.device(request.param) @@ -30,6 +42,8 @@ def random_surface( The up coordinates. factor : float Factor determining how deformed the surface is. + device : torch.device + The device on which to initialize tensors. Returns ------- @@ -60,6 +74,11 @@ def test_nurbs(device: torch.device) -> None: ---------- device : torch.device The device on which to initialize tensors. + + Raises + ------ + AssertionError + If test does not complete as expected. """ torch.manual_seed(7) torch.cuda.manual_seed(7) diff --git a/tests/field/test_rigid_body.py b/tests/field/test_rigid_body.py index a9d67b5b..47663e26 100644 --- a/tests/field/test_rigid_body.py +++ b/tests/field/test_rigid_body.py @@ -14,15 +14,34 @@ ) -@pytest.fixture(params=["cpu", "cuda:3"] if torch.cuda.is_available() else ["cpu"]) +@pytest.fixture(params=["cpu", "cuda"] if torch.cuda.is_available() else ["cpu"]) def device(request: pytest.FixtureRequest) -> torch.device: - """Return the device on which to initialize tensors.""" + """ + Return the device on which to initialize tensors. + + Parameters + ---------- + request : pytest.FixtureRequest + The pytest fixture used to consider different test cases. + + Returns + ------- + torch.device + The device on which to initialize tensors. + """ return torch.device(request.param) @pytest.fixture def actuator_configuration() -> ActuatorListConfig: - """Define actuator parameters used in tests.""" + """ + Define actuator parameters used in tests. + + Returns + ------- + ActuatorListConfig + A List containing parameters for each actuator. + """ actuator1_config = ActuatorConfig( actuator_key="", actuator_type=config_dictionary.ideal_actuator_key, @@ -37,8 +56,20 @@ def actuator_configuration() -> ActuatorListConfig: @pytest.fixture -def initial_offsets_south(device) -> KinematicOffsets: - """Define initial offsets for a south-orientated heliostat.""" +def initial_offsets_south(device: torch.device) -> KinematicOffsets: + """ + Define initial offsets for a south-orientated heliostat. + + Parameters + ---------- + device : torch.device + The device on which to initialize tensors. + + Returns + ------- + KinematicOffsets + Initial kinematic offsets for a south-orientated heliostat. + """ initial_offsets = KinematicOffsets( kinematic_initial_orientation_offset_e=torch.tensor(0.0, device=device), kinematic_initial_orientation_offset_n=torch.tensor(0.0, device=device), @@ -48,8 +79,20 @@ def initial_offsets_south(device) -> KinematicOffsets: @pytest.fixture -def initial_offsets_above(device) -> KinematicOffsets: - """Define initial offsets for an up-orientated heliostat.""" +def initial_offsets_above(device: torch.device) -> KinematicOffsets: + """ + Define initial offsets for an up-orientated heliostat. + + Parameters + ---------- + device : torch.device + The device on which to initialize tensors. + + Returns + ------- + KinematicOffsets + Initial kinematic offsets for an up-orientated heliostat. + """ initial_offsets = KinematicOffsets( kinematic_initial_orientation_offset_e=torch.tensor(math.pi / 2, device=device), kinematic_initial_orientation_offset_n=torch.tensor(0.0, device=device), @@ -75,6 +118,11 @@ def kinematic_model_1( The kinematic initial orientation offsets. device : torch.device The device on which to initialize tensors. + + Returns + ------- + RigidBody + The kinematic model. """ position = torch.tensor([0.0, 0.0, 0.0, 1.0], device=device) aim_point = torch.tensor([0.0, -10.0, 0.0, 1.0], device=device) @@ -104,6 +152,11 @@ def kinematic_model_2( The kinematic initial orientation offsets. device : torch.device The device on which to initialize tensors. + + Returns + ------- + RigidBody + The kinematic model. """ position = torch.tensor([0.0, 1.0, 0.0, 1.0], device=device) aim_point = torch.tensor([0.0, -9.0, 0.0, 1.0], device=device) @@ -133,6 +186,11 @@ def kinematic_model_3( The kinematic initial orientation offsets. device : torch.device The device on which to initialize tensors. + + Returns + ------- + RigidBody + The kinematic model. """ position = torch.tensor([0.0, 0.0, 0.0, 1.0], device=device) aim_point = torch.tensor([0.0, -10.0, 0.0, 1.0], device=device) @@ -292,6 +350,11 @@ def test_orientation_matrix( The expected orientation matrix. device : torch.device The device on which to initialize tensors. + + Raises + ------ + AssertionError + If test does not complete as expected. """ orientation_matrix = request.getfixturevalue(kinematic_model_fixture).align( incident_ray_direction.to(device), device=device diff --git a/tests/raytracing/test_line_plane_intersection.py b/tests/raytracing/test_line_plane_intersection.py index 34b45ff1..b325859c 100644 --- a/tests/raytracing/test_line_plane_intersection.py +++ b/tests/raytracing/test_line_plane_intersection.py @@ -6,9 +6,21 @@ from artist.raytracing import raytracing_utils -@pytest.fixture(params=["cpu", "cuda:3"] if torch.cuda.is_available() else ["cpu"]) +@pytest.fixture(params=["cpu", "cuda"] if torch.cuda.is_available() else ["cpu"]) def device(request: pytest.FixtureRequest) -> torch.device: - """Return the device on which to initialize tensors.""" + """ + Return the device on which to initialize tensors. + + Parameters + ---------- + request : pytest.FixtureRequest + The pytest fixture used to consider different test cases. + + Returns + ------- + torch.device + The device on which to initialize tensors. + """ return torch.device(request.param) @@ -90,6 +102,11 @@ def test_line_plane_intersection( The expected intersections between the rays and the plane, or ``None`` if no intersections are expected. device : torch.device The device on which to initialize tensors. + + Raises + ------ + AssertionError + If test does not complete as expected. """ if expected_intersections is None: # Check if an AssertionError is thrown as expected. diff --git a/tests/raytracing/test_reflect.py b/tests/raytracing/test_reflect.py index 697f51e5..245bc899 100644 --- a/tests/raytracing/test_reflect.py +++ b/tests/raytracing/test_reflect.py @@ -4,9 +4,21 @@ from artist.raytracing import raytracing_utils -@pytest.fixture(params=["cpu", "cuda:3"] if torch.cuda.is_available() else ["cpu"]) +@pytest.fixture(params=["cpu", "cuda"] if torch.cuda.is_available() else ["cpu"]) def device(request: pytest.FixtureRequest) -> torch.device: - """Return the device on which to initialize tensors.""" + """ + Return the device on which to initialize tensors. + + Parameters + ---------- + request : pytest.FixtureRequest + The pytest fixture used to consider different test cases. + + Returns + ------- + torch.device + The device on which to initialize tensors. + """ return torch.device(request.param) @@ -63,6 +75,11 @@ def test_reflect_function( The expected direction of the reflected rays. device : torch.device The device on which to initialize tensors. + + Raises + ------ + AssertionError + If test does not complete as expected. """ reflection = raytracing_utils.reflect( incoming_ray_direction=incoming_ray_direction.to(device), diff --git a/tests/scene/test_light_source.py b/tests/scene/test_light_source.py index ddc80863..997133b7 100644 --- a/tests/scene/test_light_source.py +++ b/tests/scene/test_light_source.py @@ -7,9 +7,21 @@ from artist.util import config_dictionary -@pytest.fixture(params=["cpu", "cuda:3"] if torch.cuda.is_available() else ["cpu"]) +@pytest.fixture(params=["cpu", "cuda"] if torch.cuda.is_available() else ["cpu"]) def device(request: pytest.FixtureRequest) -> torch.device: - """Return the device on which to initialize tensors.""" + """ + Return the device on which to initialize tensors. + + Parameters + ---------- + request : pytest.FixtureRequest + The pytest fixture used to consider different test cases. + + Returns + ------- + torch.device + The device on which to initialize tensors. + """ return torch.device(request.param) @@ -65,7 +77,14 @@ def calculate_expected( @pytest.fixture def distribution_parameters_1() -> Dict[str, Any]: - """Fixture that returns distribution parameters for the sun.""" + """ + Fixture that returns distribution parameters for the sun. + + Returns + ------- + Dict[str, Any] + Distribution parameters for the sun. + """ return { config_dictionary.light_source_distribution_type: config_dictionary.light_source_distribution_is_normal, config_dictionary.light_source_mean: 0, @@ -75,7 +94,14 @@ def distribution_parameters_1() -> Dict[str, Any]: @pytest.fixture def distribution_parameters_2() -> Dict[str, Any]: - """Fixture that returns distribution parameters for the sun.""" + """ + Fixture that returns distribution parameters for the sun. + + Returns + ------- + Dict[str, Any] + Distribution parameters for the sun. + """ return { config_dictionary.light_source_distribution_type: config_dictionary.light_source_distribution_is_normal, config_dictionary.light_source_mean: 0, @@ -85,7 +111,14 @@ def distribution_parameters_2() -> Dict[str, Any]: @pytest.fixture def distribution_parameters_3() -> Dict[str, Any]: - """Fixture that returns distribution parameters for the sun.""" + """ + Fixture that returns distribution parameters for the sun. + + Returns + ------- + Dict[str, Any] + Distribution parameters for the sun. + """ return { config_dictionary.light_source_distribution_type: config_dictionary.light_source_distribution_is_normal, config_dictionary.light_source_mean: 10, @@ -95,7 +128,14 @@ def distribution_parameters_3() -> Dict[str, Any]: @pytest.fixture def further_parameters_1() -> Dict[str, int]: - """Fixture that returns further test parameters.""" + """ + Fixture that returns further test parameters. + + Returns + ------- + Dict[str, int] + Further test parameters. + """ return { "num_rays": 100, "num_points": 50, @@ -107,7 +147,14 @@ def further_parameters_1() -> Dict[str, int]: @pytest.fixture def further_parameters_2() -> Dict[str, int]: - """Fixture that returns further test parameters.""" + """ + Fixture that returns further test parameters. + + Returns + ------- + Dict[str, int] + Further test parameters. + """ return { "num_rays": 100, "num_points": 50, @@ -119,7 +166,14 @@ def further_parameters_2() -> Dict[str, int]: @pytest.fixture def further_parameters_3() -> Dict[str, int]: - """Fixture that returns further test parameters.""" + """ + Fixture that returns further test parameters. + + Returns + ------- + Dict[str, int] + Further test parameters. + """ return { "num_rays": 20, "num_points": 300, @@ -165,6 +219,11 @@ def test_light_sources( The pytest fixture containing the further test parameters. device : torch.device The device on which to initialize tensors. + + Raises + ------ + AssertionError + If test does not complete as expected. """ # Load further params dict. further_params_dict = request.getfixturevalue(further_parameters_fixture) diff --git a/tests/util/test_distortion_rotations.py b/tests/util/test_distortion_rotations.py index b3d94333..1a604fdf 100644 --- a/tests/util/test_distortion_rotations.py +++ b/tests/util/test_distortion_rotations.py @@ -6,9 +6,21 @@ from artist.util.utils import rotate_distortions -@pytest.fixture(params=["cpu", "cuda:3"] if torch.cuda.is_available() else ["cpu"]) +@pytest.fixture(params=["cpu", "cuda"] if torch.cuda.is_available() else ["cpu"]) def device(request: pytest.FixtureRequest) -> torch.device: - """Return the device on which to initialize tensors.""" + """ + Return the device on which to initialize tensors. + + Parameters + ---------- + request : pytest.FixtureRequest + The pytest fixture used to consider different test cases. + + Returns + ------- + torch.device + The device on which to initialize tensors. + """ return torch.device(request.param) @@ -289,6 +301,11 @@ def test_distortion_rotations( The expected distorted rays after rotation. device : torch.device The device on which to initialize tensors. + + Raises + ------ + AssertionError + If test does not complete as expected. """ distorted_rays = ( rotate_distortions(