Best JavaScript code snippet using wpt
debug_data.py
Source:debug_data.py
1# Copyright 2016 The TensorFlow Authors. All Rights Reserved.2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14# ==============================================================================15"""Classes and functions to handle debug-dump data of TensorFlow Debugger."""16from __future__ import absolute_import17from __future__ import division18from __future__ import print_function19import collections20import glob21import json22import os23import numpy as np24import six25from six.moves import xrange # pylint: disable=redefined-builtin26from tensorflow.core.framework import graph_pb227from tensorflow.core.framework import types_pb228from tensorflow.core.util import event_pb229from tensorflow.python.framework import tensor_util30from tensorflow.python.platform import gfile31# TODO(cais): Tie these string constants in with C++?32METADATA_FILE_PREFIX = "_tfdbg_"33CORE_METADATA_TAG = "core_metadata_"34GRAPH_FILE_TAG = "graph_"35DEVICE_TAG = "device_"36FETCHES_INFO_FILE_TAG = "fetches_info_"37FEED_KEYS_INFO_FILE_TAG = "feed_keys_info_"38class InconvertibleTensorProto(object):39 """Represents a TensorProto that cannot be converted to np.ndarray."""40 def __init__(self, tensor_proto, initialized=True):41 """Constructor.42 Args:43 tensor_proto: the `TensorProto` object that cannot be represented as a44 `np.ndarray` object.45 initialized: (`bool`) whether the Tensor is initialized.46 """47 self._tensor_proto = tensor_proto48 self._initialized = initialized49 def __str__(self):50 output = "" if self._initialized else "Uninitialized tensor:\n"51 output += str(self._tensor_proto)52 return output53 @property54 def initialized(self):55 return self._initialized56def load_tensor_from_event_file(event_file_path):57 """Load a tensor from an event file.58 Assumes that the event file contains a `Event` protobuf and the `Event`59 protobuf contains a `Tensor` value.60 Args:61 event_file_path: (`str`) path to the event file.62 Returns:63 The tensor value loaded from the event file, as a `numpy.ndarray`. For64 uninitialized Tensors, returns `None`. For Tensors of data types that65 cannot be converted to `numpy.ndarray` (e.g., `tf.resource`), return66 `None`.67 """68 event = event_pb2.Event()69 with gfile.Open(event_file_path, "rb") as f:70 event.ParseFromString(f.read())71 return load_tensor_from_event(event)72def load_tensor_from_event(event):73 """Load a tensor from an Event proto.74 Args:75 event: The Event proto, assumed to hold a tensor value in its76 summary.value[0] field.77 Returns:78 The tensor value loaded from the event file, as a `numpy.ndarray`, if79 representation of the tensor value by a `numpy.ndarray` is possible.80 For uninitialized Tensors, returns `None`. For Tensors of data types that81 cannot be represented as `numpy.ndarray` (e.g., `tf.resource`), return82 the `TensorProto` protobuf object without converting it to a83 `numpy.ndarray`.84 """85 tensor_proto = event.summary.value[0].tensor86 if tensor_proto.tensor_content or tensor_proto.string_val:87 # Initialized tensor.88 if tensor_proto.dtype == types_pb2.DT_RESOURCE:89 tensor_value = InconvertibleTensorProto(tensor_proto)90 else:91 try:92 tensor_value = tensor_util.MakeNdarray(tensor_proto)93 except KeyError:94 tensor_value = InconvertibleTensorProto(tensor_proto)95 else:96 # Uninitialized tensor or tensor of unconvertible data type.97 tensor_value = InconvertibleTensorProto(tensor_proto, False)98 return tensor_value99def _load_graph_def_from_event_file(event_file_path):100 event = event_pb2.Event()101 with gfile.Open(event_file_path, "rb") as f:102 event.ParseFromString(f.read())103 return graph_pb2.GraphDef.FromString(event.graph_def)104def _load_log_message_from_event_file(event_file_path):105 event = event_pb2.Event()106 with gfile.Open(event_file_path, "rb") as f:107 event.ParseFromString(f.read())108 return event.log_message.message109def parse_node_or_tensor_name(name):110 """Get the node name from a string that can be node or tensor name.111 Args:112 name: An input node name (e.g., "node_a") or tensor name (e.g.,113 "node_a:0"), as a str.114 Returns:115 1) The node name, as a str. If the input name is a tensor name, i.e.,116 consists of a colon, the final colon and the following output slot117 will be stripped.118 2) If the input name is a tensor name, the output slot, as an int. If119 the input name is not a tensor name, None.120 """121 if ":" in name and not name.endswith(":"):122 node_name = name[:name.rfind(":")]123 output_slot = int(name[name.rfind(":") + 1:])124 return node_name, output_slot125 else:126 return name, None127def _is_graph_file(file_name):128 return file_name.startswith(METADATA_FILE_PREFIX + GRAPH_FILE_TAG)129def _is_run_fetches_info_file(file_name):130 return file_name == METADATA_FILE_PREFIX + FETCHES_INFO_FILE_TAG131def _is_run_feed_keys_info_file(file_name):132 return file_name == METADATA_FILE_PREFIX + FEED_KEYS_INFO_FILE_TAG133def get_node_name(element_name):134 return element_name.split(":")[0] if ":" in element_name else element_name135def get_output_slot(element_name):136 """Get the output slot number from the name of a graph element.137 If element_name is a node name without output slot at the end, 0 will be138 assumed.139 Args:140 element_name: (`str`) name of the graph element in question.141 Returns:142 (`int`) output slot number.143 """144 return int(element_name.split(":")[-1]) if ":" in element_name else 0145def _get_tensor_name(node_name, output_slot):146 """Get tensor name given node name and output slot index.147 Args:148 node_name: Name of the node that outputs the tensor, as a string.149 output_slot: Output slot index of the tensor, as an integer.150 Returns:151 Name of the tensor, as a string.152 """153 return "%s:%d" % (node_name, output_slot)154def _get_tensor_watch_key(node_name, output_slot, debug_op):155 """Get the string representation of a debug watch on a tensor.156 Args:157 node_name: Name of the node by which the watched tensor is produced, as a158 string.159 output_slot: Output slot index of the tensor, as an integer.160 debug_op: Name of the debug op that is used to watch the tensor, as a161 string.162 Returns:163 A string representing the debug watch on the tensor (i.e., the "watch164 key").165 """166 return "%s:%s" % (_get_tensor_name(node_name, output_slot), debug_op)167def is_copy_node(node_name):168 """Determine whether a node name is that of a debug Copy node.169 Such nodes are inserted by TensorFlow core upon request in170 RunOptions.debug_options.debug_tensor_watch_opts.171 Args:172 node_name: Name of the node.173 Returns:174 A bool indicating whether the input argument is the name of a debug Copy175 node.176 """177 return node_name.startswith("__copy_")178def is_debug_node(node_name):179 """Determine whether a node name is that of a debug node.180 Such nodes are inserted by TensorFlow core upon request in181 RunOptions.debug_options.debug_tensor_watch_opts.182 Args:183 node_name: Name of the node.184 Returns:185 A bool indicating whether the input argument is the name of a debug node.186 """187 return node_name.startswith("__dbg_")188def parse_debug_node_name(node_name):189 """Parse the name of a debug node.190 Args:191 node_name: Name of the debug node.192 Returns:193 1. Name of the watched node, as a str.194 2. Output slot index of the watched tensor, as an int.195 3. Index of the debug node, as an int.196 4. Name of the debug op, as a str, e.g, "DebugIdentity".197 Raises:198 ValueError: If the input node name is not a valid debug node name.199 """200 prefix = "__dbg_"201 name = node_name202 if not name.startswith(prefix):203 raise ValueError("Invalid prefix in debug node name: '%s'" % node_name)204 name = name[len(prefix):]205 if name.count("_") < 2:206 raise ValueError("Invalid debug node name: '%s'" % node_name)207 debug_op = name[name.rindex("_") + 1:]208 name = name[:name.rindex("_")]209 debug_op_index = int(name[name.rindex("_") + 1:])210 name = name[:name.rindex("_")]211 if name.count(":") != 1:212 raise ValueError("Invalid tensor name in debug node name: '%s'" % node_name)213 watched_node_name = name[:name.index(":")]214 watched_output_slot = int(name[name.index(":") + 1:])215 return watched_node_name, watched_output_slot, debug_op_index, debug_op216def has_inf_or_nan(datum, tensor):217 """A predicate for whether a tensor consists of any bad numerical values.218 This predicate is common enough to merit definition in this module.219 Bad numerical values include `nan`s and `inf`s.220 The signature of this function follows the requirement of the method221 `DebugDumpDir.find()`.222 Args:223 datum: (`DebugTensorDatum`) Datum metadata.224 tensor: (`numpy.ndarray` or None) Value of the tensor. None represents225 an uninitialized tensor.226 Returns:227 (`bool`) True if and only if tensor consists of any nan or inf values.228 """229 _ = datum # Datum metadata is unused in this predicate.230 if isinstance(tensor, InconvertibleTensorProto):231 # Uninitialized tensor doesn't have bad numerical values.232 # Also return False for data types that cannot be represented as numpy233 # arrays.234 return False235 elif (np.issubdtype(tensor.dtype, np.float) or236 np.issubdtype(tensor.dtype, np.complex) or237 np.issubdtype(tensor.dtype, np.integer)):238 return np.any(np.isnan(tensor)) or np.any(np.isinf(tensor))239 else:240 return False241_CoreMetadata = collections.namedtuple("CoreMetadata", [242 "global_step", "session_run_index", "executor_step_index", "input_names",243 "output_names", "target_nodes"244])245def extract_core_metadata_from_event_proto(event):246 json_metadata = json.loads(event.log_message.message)247 return _CoreMetadata(json_metadata["global_step"],248 json_metadata["session_run_index"],249 json_metadata["executor_step_index"],250 json_metadata["input_names"],251 json_metadata["output_names"],252 json_metadata["target_nodes"])253def device_name_to_device_path(device_name):254 """Convert device name to device path."""255 device_name_items = device_name.split("/")256 device_name_items = [item.replace(":", "_") for item in device_name_items]257 return METADATA_FILE_PREFIX + DEVICE_TAG + ",".join(device_name_items)258def device_path_to_device_name(device_dir):259 """Parse device name from device path.260 Args:261 device_dir: (str) a directory name for the device.262 Returns:263 (str) parsed device name.264 """265 path_items = os.path.basename(device_dir)[266 len(METADATA_FILE_PREFIX) + len(DEVICE_TAG):].split(",")267 return "/".join([268 path_item.replace("_", ":", 1) for path_item in path_items])269class DebugTensorDatum(object):270 """A single tensor dumped by TensorFlow Debugger (tfdbg).271 Contains metadata about the dumped tensor, including `timestamp`,272 `node_name`, `output_slot`, `debug_op`, and path to the dump file273 (`file_path`).274 This type does not hold the generally space-expensive tensor value (numpy275 array). Instead, it points to the file from which the tensor value can be276 loaded (with the `get_tensor` method) if needed.277 """278 def __init__(self, dump_root, debug_dump_rel_path):279 """`DebugTensorDatum` constructor.280 Args:281 dump_root: (`str`) Debug dump root directory. This path should not include282 the path component that represents the device name (see also below).283 debug_dump_rel_path: (`str`) Path to a debug dump file, relative to the284 `dump_root`. The first item of this relative path is assumed to be285 a path representing the name of the device that the Tensor belongs to.286 See `device_path_to_device_name` for more details on the device path.287 For example, suppose the debug dump root288 directory is `/tmp/tfdbg_1` and the dump file is at289 `/tmp/tfdbg_1/<device_path>/>ns_1/node_a_0_DebugIdentity_123456789`,290 then the value of the debug_dump_rel_path should be291 `<device_path>/ns_1/node_a_0_DebugIdenity_1234456789`.292 Raises:293 ValueError: If the base file name of the dump file does not conform to294 the dump file naming pattern:295 `node_name`_`output_slot`_`debug_op`_`timestamp`296 """297 path_components = os.path.normpath(debug_dump_rel_path).split(os.sep)298 self._device_name = device_path_to_device_name(path_components[0])299 base = path_components[-1]300 if base.count("_") < 3:301 raise ValueError(302 "Dump file path does not conform to the naming pattern: %s" % base)303 self._extended_timestamp = base.split("_")[-1]304 # It may include an index suffix at the end if file path collision happened305 # due to identical timestamps.306 if "-" in self._extended_timestamp:307 self._timestamp = int(308 self._extended_timestamp[:self._extended_timestamp.find("-")])309 else:310 self._timestamp = int(self._extended_timestamp)311 self._debug_op = base.split("_")[-2]312 self._output_slot = int(base.split("_")[-3])313 node_base_name = "_".join(base.split("_")[:-3])314 self._node_name = "/".join(path_components[1:-1] + [node_base_name])315 self._file_path = os.path.join(dump_root, debug_dump_rel_path)316 self._dump_size_bytes = (gfile.Stat(self._file_path).length if317 gfile.Exists(self._file_path) else None)318 def __str__(self):319 return "{DebugTensorDatum (%s) %s:%d @ %s @ %d}" % (self.device_name,320 self.node_name,321 self.output_slot,322 self.debug_op,323 self.timestamp)324 def __repr__(self):325 return self.__str__()326 def get_tensor(self):327 """Get tensor from the dump (`Event`) file.328 Returns:329 The tensor loaded from the dump (`Event`) file.330 """331 return load_tensor_from_event_file(self.file_path)332 # TODO(cais): Add time unit suffix to timestamp and t0 (us).333 @property334 def timestamp(self):335 """Timestamp of when this tensor value was dumped.336 Returns:337 (`int`) The timestamp in microseconds.338 """339 return self._timestamp340 @property341 def extended_timestamp(self):342 """Extended timestamp, possibly with an index suffix.343 The index suffix, e.g., "-1", is for disambiguating multiple dumps of the344 same tensor with the same timestamp, which can occur if the dumping events345 are spaced by shorter than the temporal resolution of the timestamps.346 Returns:347 (`str`) The extended timestamp.348 """349 return self._extended_timestamp350 @property351 def debug_op(self):352 """Name of the debug op.353 Returns:354 (`str`) debug op name (e.g., `DebugIdentity`).355 """356 return self._debug_op357 @property358 def device_name(self):359 """Name of the device that the tensor belongs to.360 Returns:361 (`str`) device name.362 """363 return self._device_name364 @property365 def node_name(self):366 """Name of the node from which the tensor value was dumped.367 Returns:368 (`str`) name of the node watched by the debug op.369 """370 return self._node_name371 @property372 def output_slot(self):373 """Output slot index from which the tensor value was dumped.374 Returns:375 (`int`) output slot index watched by the debug op.376 """377 return self._output_slot378 @property379 def tensor_name(self):380 """Name of the tensor watched by the debug op.381 Returns:382 (`str`) `Tensor` name, in the form of `node_name`:`output_slot`383 """384 return _get_tensor_name(self.node_name, self.output_slot)385 @property386 def watch_key(self):387 """Watch key identities a debug watch on a tensor.388 Returns:389 (`str`) A watch key, in the form of `tensor_name`:`debug_op`.390 """391 return _get_tensor_watch_key(self.node_name, self.output_slot,392 self.debug_op)393 @property394 def file_path(self):395 """Path to the file which stores the value of the dumped tensor."""396 return self._file_path397 @property398 def dump_size_bytes(self):399 """Size of the dump file.400 Unit: byte.401 Returns:402 If the dump file exists, size of the dump file, in bytes.403 If the dump file does not exist, None.404 """405 return self._dump_size_bytes406class WatchKeyDoesNotExistInDebugDumpDirError(ValueError):407 pass408# TODO(cais): This class is getting too large in line count. Refactor to make it409# smaller and easier to maintain.410class DebugDumpDir(object):411 """Data set from a debug-dump directory on filesystem.412 An instance of `DebugDumpDir` contains all `DebugTensorDatum` instances413 in a tfdbg dump root directory.414 """415 def __init__(self, dump_root, partition_graphs=None, validate=True):416 """`DebugDumpDir` constructor.417 Args:418 dump_root: (`str`) path to the dump root directory.419 partition_graphs: A repeated field of GraphDefs representing the420 partition graphs executed by the TensorFlow runtime.421 validate: (`bool`) whether the dump files are to be validated against the422 partition graphs.423 Raises:424 IOError: If dump_root does not exist as a directory.425 ValueError: If more than one core metadata file is found under the dump426 root directory.427 """428 if not gfile.IsDirectory(dump_root):429 raise IOError("Dump root directory %s does not exist" % dump_root)430 self._core_metadata = []431 # Find the list of devices.432 self._dump_root = dump_root433 self._load_core_metadata()434 self._load_fetches_info()435 self._load_feeds_info()436 self._load_all_device_dumps(partition_graphs, validate)437 self._python_graph = None438 def _load_all_device_dumps(self, partition_graphs, validate):439 """Load the dump data for all devices."""440 device_dirs = glob.glob(os.path.join(441 self._dump_root, METADATA_FILE_PREFIX + DEVICE_TAG + "*"))442 self._device_names = []443 self._t0s = {}444 self._dump_tensor_data = {}445 self._dump_graph_file_paths = {}446 self._debug_watches = {}447 self._watch_key_to_devices = {}448 self._watch_key_to_datum = {}449 self._watch_key_to_rel_time = {}450 self._watch_key_to_dump_size_bytes = {}451 for device_dir in device_dirs:452 device_name = device_path_to_device_name(device_dir)453 self._device_names.append(device_name)454 self._load_device_dumps(device_name, device_dir)455 self._load_partition_graphs(partition_graphs, validate)456 self._calculate_t0()457 for device_name in self._device_names:458 self._create_tensor_watch_maps(device_name)459 def _load_device_dumps(self, device_name, device_root):460 """Load `DebugTensorDatum` instances from the dump root of a given device.461 Populates a map {device_name: a list of `DebugTensorDatum`}, where the list462 is sorted by ascending timestamp.463 This sorting order reflects the order in which the TensorFlow executor464 processed the nodes of the graph. It is (one of many possible) topological465 sort of the nodes. This is useful for displaying tensors in the debugger466 frontend as well as for the use case in which the user wants to find a467 "culprit tensor", i.e., the first tensor in the graph that exhibits certain468 problematic properties, i.e., all zero values, or bad numerical values such469 as nan and inf.470 In addition, creates a map from node name to debug watches. In this Map,471 the key is the watched node name; the value is a dictionary.472 Of this dictionary, the key is the watched_output_slot.473 This method attempts to load the debug watches from the tensor dump files474 first, before loading the full set of debug watches from the partition475 graphs as done later. This is necessary because sometimes the partition476 graphs may not be available, e.g., when the run errors out.477 Args:478 device_name: (`str`) name of the device.479 device_root: (`str`) dump root directory of the given device.480 Raises:481 ValueError: If GraphDef for the device is not available.482 """483 self._dump_tensor_data[device_name] = []484 self._debug_watches[device_name] = collections.defaultdict(485 lambda: collections.defaultdict(set))486 for root, _, files in gfile.Walk(device_root):487 for f in files:488 if _is_graph_file(f):489 self._dump_graph_file_paths[device_name] = os.path.join(490 device_root, root, f)491 else:492 datum = self._dump_file_name_to_datum(root, f)493 self._dump_tensor_data[device_name].append(datum)494 self._debug_watches[device_name][datum.node_name][495 datum.output_slot].add(datum.debug_op)496 self._dump_tensor_data[device_name] = sorted(497 self._dump_tensor_data[device_name],498 key=lambda x: x.extended_timestamp)499 if self._dump_tensor_data[device_name]:500 self._t0s[device_name] = self._dump_tensor_data[device_name][0].timestamp501 else:502 self._t0s[device_name] = None503 def _calculate_t0(self):504 """Calculate the first timestamp across all devices."""505 t0s = [t0 for t0 in six.itervalues(self._t0s) if t0 is not None]506 self._t0 = min(t0s) if t0s else None507 def _load_core_metadata(self):508 core_metadata_files = glob.glob(os.path.join(509 self._dump_root, METADATA_FILE_PREFIX + CORE_METADATA_TAG + "*"))510 for core_metadata_file in core_metadata_files:511 with gfile.Open(core_metadata_file, "rb") as f:512 event = event_pb2.Event()513 event.ParseFromString(f.read())514 self._core_metadata.append(515 extract_core_metadata_from_event_proto(event))516 def _load_fetches_info(self):517 fetches_info_files = glob.glob(os.path.join(518 self._dump_root, METADATA_FILE_PREFIX + FETCHES_INFO_FILE_TAG + "*"))519 self._run_fetches_info = []520 for fetches_info_file in fetches_info_files:521 self._run_fetches_info.append(522 _load_log_message_from_event_file(fetches_info_file))523 def _load_feeds_info(self):524 feeds_info_files = glob.glob(os.path.join(525 self._dump_root, METADATA_FILE_PREFIX + FEED_KEYS_INFO_FILE_TAG + "*"))526 self._run_feed_keys_info = []527 for feeds_info_file in feeds_info_files:528 self._run_feed_keys_info.append(529 _load_log_message_from_event_file(feeds_info_file))530 def _dump_file_name_to_datum(self, dir_name, file_name):531 """Obtain a DebugTensorDatum from the directory and file name.532 Args:533 dir_name: (`str`) Name of the directory in which the dump file resides.534 file_name: (`str`) Base name of the dump file.535 Returns:536 (`DebugTensorDatum`) The `DebugTensorDatum` loaded from the dump file.537 """538 # Calculate the relative path of the dump file with respect to the root.539 debug_dump_rel_path = os.path.join(540 os.path.relpath(dir_name, self._dump_root), file_name)541 return DebugTensorDatum(self._dump_root, debug_dump_rel_path)542 def _create_tensor_watch_maps(self, device_name):543 """Create maps from tensor watch keys to datum and to timestamps.544 Create a map from watch key (tensor name + debug op) to `DebugTensorDatum`545 item. Also make a map from watch key to relative timestamp.546 "relative" means (absolute timestamp - t0).547 Args:548 device_name: (str) name of the device.549 """550 self._watch_key_to_datum[device_name] = {}551 self._watch_key_to_rel_time[device_name] = {}552 self._watch_key_to_dump_size_bytes[device_name] = {}553 for datum in self._dump_tensor_data[device_name]:554 if datum.watch_key not in self._watch_key_to_devices:555 self._watch_key_to_devices[datum.watch_key] = {device_name}556 else:557 self._watch_key_to_devices[datum.watch_key].add(device_name)558 if datum.watch_key not in self._watch_key_to_datum[device_name]:559 self._watch_key_to_datum[device_name][datum.watch_key] = [datum]560 self._watch_key_to_rel_time[device_name][datum.watch_key] = [561 datum.timestamp - self._t0]562 self._watch_key_to_dump_size_bytes[device_name][datum.watch_key] = [563 datum.dump_size_bytes]564 else:565 self._watch_key_to_datum[device_name][datum.watch_key].append(datum)566 self._watch_key_to_rel_time[device_name][datum.watch_key].append(567 datum.timestamp - self._t0)568 self._watch_key_to_dump_size_bytes[device_name][datum.watch_key].append(569 datum.dump_size_bytes)570 def set_python_graph(self, python_graph):571 """Provide Python `Graph` object to the wrapper.572 Unlike the partition graphs, which are protobuf `GraphDef` objects, `Graph`573 is a Python object and carries additional information such as the traceback574 of the construction of the nodes in the graph.575 Args:576 python_graph: (ops.Graph) The Python Graph object.577 """578 self._python_graph = python_graph579 self._node_traceback = {}580 if self._python_graph:581 for op in self._python_graph.get_operations():582 self._node_traceback[op.name] = op.traceback583 @property584 def python_graph(self):585 """Get the Python graph.586 Returns:587 If the Python graph has been set, returns a `tf.Graph` object. Otherwise,588 returns None.589 """590 return self._python_graph591 @property592 def core_metadata(self):593 """Metadata about the `Session.run()` call from the core runtime.594 Of the three counters available in the return value, `global_step` is595 supplied by the caller of the debugged `Session.run()`, while596 `session_run_index` and `executor_step_index` are determined by the state597 of the core runtime, automatically. For the same fetch list, feed keys and598 debug tensor watch options, the same executor will be used and599 `executor_step_index` should increase by one at a time. However, runs with600 different fetch lists, feed keys and debug_tensor watch options that all601 share the same `Session` object can lead to gaps in `session_run_index`.602 Returns:603 If core metadata are loaded, a `namedtuple` with the fields:604 `global_step`: A global step count supplied by the caller of605 `Session.run()`. It is optional to the caller. If the caller did not606 supply this parameter, its value will be -1.607 `session_run_index`: A sorted index for Run() calls to the underlying608 TensorFlow `Session` object.609 `executor_step_index`: A counter for invocations of a given runtime610 executor. The same executor is re-used for the same fetched tensors,611 target nodes, input feed keys and debug tensor watch options.612 `input_names`: Names of the input (feed) Tensors.613 `output_names`: Names of the output (fetched) Tensors.614 `target_nodes`: Names of the target nodes.615 If the core metadata have not been loaded, `None`.616 If more than one core metadata files exist, return a list of the617 `nametuple` described above.618 """619 output = self._core_metadata620 return output[0] if len(output) == 1 else output621 @property622 def dumped_tensor_data(self):623 """Retrieve dumped tensor data."""624 if len(self.devices()) == 1:625 return self._dump_tensor_data[self.devices()[0]]626 else:627 all_devices_data = six.itervalues(self._dump_tensor_data)628 data = []629 for device_data in all_devices_data:630 data.extend(device_data)631 return sorted(data, key=lambda x: x.extended_timestamp)632 @property633 def t0(self):634 """Absolute timestamp of the first dumped tensor across all devices.635 Returns:636 (`int`) absolute timestamp of the first dumped tensor, in microseconds.637 """638 return self._t0639 @property640 def size(self):641 """Total number of dumped tensors in the dump root directory.642 Returns:643 (`int`) The total number of dumped tensors in the dump root directory.644 """645 return sum(len(self._dump_tensor_data[device_name])646 for device_name in self._dump_tensor_data)647 def _load_partition_graphs(self, partition_graphs, validate):648 """Load and process partition graphs.649 Load the graphs; parse the input and control input structure; obtain the650 device and op type of each node; remove the Copy and debug ops inserted651 by the debugger. The gathered information can be used to validate the652 tensor dumps.653 Args:654 partition_graphs: A repeated field of GraphDefs representing the655 partition graphs executed by the TensorFlow runtime.656 validate: (`bool`) Whether the dump files are to be validated against the657 partition graphs.658 Raises:659 ValueError: If the partition GraphDef of one or more devices fail to be660 loaded.661 """662 self._node_attributes = {}663 self._node_inputs = {}664 self._node_ctrl_inputs = {}665 self._node_recipients = {}666 self._node_ctrl_recipients = {}667 self._node_devices = {}668 self._node_op_types = {}669 self._copy_send_nodes = {}670 self._partition_graphs = {}671 for device_name in self._device_names:672 partition_graph = None673 if device_name in self._dump_graph_file_paths:674 partition_graph = _load_graph_def_from_event_file(675 self._dump_graph_file_paths[device_name])676 else:677 partition_graph = self._find_partition_graph(partition_graphs,678 device_name)679 if partition_graph:680 self._partition_graphs[device_name] = partition_graph681 self._node_attributes[device_name] = {}682 self._node_inputs[device_name] = {}683 self._node_ctrl_inputs[device_name] = {}684 self._node_recipients[device_name] = {}685 self._node_ctrl_recipients[device_name] = {}686 self._node_op_types[device_name] = {}687 self._copy_send_nodes[device_name] = []688 if partition_graph:689 for node in partition_graph.node:690 self._process_partition_graph_node(device_name, node)691 self._prune_non_control_edges_of_debug_ops(device_name)692 self._prune_control_edges_of_debug_ops(device_name)693 self._populate_recipient_maps(device_name)694 if device_name in self._partition_graphs and validate:695 self._validate_dump_with_graphs(device_name)696 def _find_partition_graph(self, partition_graphs, device_name):697 if partition_graphs is None:698 return None699 else:700 for graph_def in partition_graphs:701 for node_def in graph_def.node:702 if node_def.device == device_name:703 return graph_def704 return None705 def _process_partition_graph_node(self, device_name, node):706 """Process a node from the partition graphs.707 Args:708 device_name: (str) device name.709 node: (NodeDef) A partition-graph node to be processed.710 Raises:711 ValueError: If duplicate node names are encountered.712 """713 if is_debug_node(node.name):714 # This is a debug node. Parse the node name and retrieve the715 # information about debug watches on tensors. But do not include716 # the node in the graph.717 (watched_node_name, watched_output_slot, _,718 debug_op) = parse_debug_node_name(node.name)719 self._debug_watches[device_name][watched_node_name][720 watched_output_slot].add(debug_op)721 return722 if node.name in self._node_inputs[device_name]:723 raise ValueError("Duplicate node name on device %s: '%s'" %724 (device_name, node.name))725 self._node_attributes[device_name][node.name] = node.attr726 self._node_inputs[device_name][node.name] = []727 self._node_ctrl_inputs[device_name][node.name] = []728 self._node_recipients[device_name][node.name] = []729 self._node_ctrl_recipients[device_name][node.name] = []730 if node.name not in self._node_devices:731 self._node_devices[node.name] = set()732 self._node_devices[node.name].add(node.device)733 self._node_op_types[device_name][node.name] = node.op734 for inp in node.input:735 if is_copy_node(inp) and (node.op == "_Send" or node.op == "_Retval"):736 self._copy_send_nodes[device_name].append(node.name)737 if inp.startswith("^"):738 cinp = inp[1:]739 self._node_ctrl_inputs[device_name][node.name].append(cinp)740 else:741 self._node_inputs[device_name][node.name].append(inp)742 def _prune_nodes_from_input_and_recipient_maps(self,743 device_name,744 nodes_to_prune):745 """Prune nodes out of input and recipient maps.746 Args:747 device_name: (`str`) device name.748 nodes_to_prune: (`list` of `str`) Names of the nodes to be pruned.749 """750 for node in nodes_to_prune:751 del self._node_inputs[device_name][node]752 del self._node_ctrl_inputs[device_name][node]753 del self._node_recipients[device_name][node]754 del self._node_ctrl_recipients[device_name][node]755 def _prune_non_control_edges_of_debug_ops(self, device_name):756 """Prune (non-control) edges related to debug ops.757 Prune the Copy ops and associated _Send ops inserted by the debugger out758 from the non-control inputs and output recipients map. Replace the inputs759 and recipients with original ones.760 Args:761 device_name: (`str`) device name.762 """763 copy_nodes = []764 for node in self._node_inputs[device_name]:765 if node in self._copy_send_nodes[device_name]:766 continue767 if is_copy_node(node):768 copy_nodes.append(node)769 inputs = self._node_inputs[device_name][node]770 for i in xrange(len(inputs)):771 inp = inputs[i]772 if is_copy_node(inp):773 # Find the input to the Copy node, which should be the original774 # input to the node.775 orig_inp = self._node_inputs[device_name][inp][0]776 inputs[i] = orig_inp777 self._prune_nodes_from_input_and_recipient_maps(device_name, copy_nodes)778 self._prune_nodes_from_input_and_recipient_maps(779 device_name, self._copy_send_nodes[device_name])780 def _prune_control_edges_of_debug_ops(self, device_name):781 """Prune control edges related to the debug ops."""782 for node in self._node_ctrl_inputs[device_name]:783 ctrl_inputs = self._node_ctrl_inputs[device_name][node]784 debug_op_inputs = []785 for ctrl_inp in ctrl_inputs:786 if is_debug_node(ctrl_inp):787 debug_op_inputs.append(ctrl_inp)788 for debug_op_inp in debug_op_inputs:789 ctrl_inputs.remove(debug_op_inp)790 def _populate_recipient_maps(self, device_name):791 """Populate the map from node name to recipient(s) of its output(s)."""792 for node in self._node_inputs[device_name]:793 inputs = self._node_inputs[device_name][node]794 for inp in inputs:795 inp = get_node_name(inp)796 if inp not in self._node_recipients[device_name]:797 self._node_recipients[device_name][inp] = []798 self._node_recipients[device_name][inp].append(node)799 for node in self._node_ctrl_inputs[device_name]:800 ctrl_inputs = self._node_ctrl_inputs[device_name][node]801 for ctrl_inp in ctrl_inputs:802 if ctrl_inp in self._copy_send_nodes[device_name]:803 continue804 if ctrl_inp not in self._node_ctrl_recipients[device_name]:805 self._node_ctrl_recipients[device_name][ctrl_inp] = []806 self._node_ctrl_recipients[device_name][ctrl_inp].append(node)807 def _validate_dump_with_graphs(self, device_name):808 """Validate the dumped tensor data against the partition graphs.809 Only the watched nodes are validated by this method, because tfdbg allows810 clients to watch only a subset of the nodes.811 Args:812 device_name: (`str`) device name.813 Raises:814 LookupError: If the partition graphs have not been loaded yet.815 ValueError: If dumps contain node names not found in partition graph.816 Or if the temporal order of the dump's timestamps violate the817 input relations on the partition graphs.818 """819 if not self._partition_graphs[device_name]:820 raise LookupError(821 "No partition graphs loaded for device %s" % device_name)822 # Verify that the node names in the dump data are all present in the823 # partition graphs.824 for datum in self._dump_tensor_data[device_name]:825 if datum.node_name not in self._node_inputs[device_name]:826 raise ValueError("Node name '%s' is not found in partition graphs of "827 "device %s." % (datum.node_name, device_name))828 pending_inputs = {}829 for node in self._node_inputs[device_name]:830 pending_inputs[node] = []831 inputs = self._node_inputs[device_name][node]832 for inp in inputs:833 inp_node = get_node_name(inp)834 inp_output_slot = get_output_slot(inp)835 # Inputs from Enter and NextIteration nodes are not validated because836 # DebugNodeInserter::InsertNodes() in the debugger core skips creating837 # control edges from debug ops watching these types of nodes.838 if (inp_node in self._debug_watches[device_name] and839 inp_output_slot in self._debug_watches[device_name][inp_node] and840 self._node_op_types[device_name].get(inp) not in (841 "Enter", "NextIteration") and842 (inp_node, inp_output_slot) not in pending_inputs[node]):843 pending_inputs[node].append((inp_node, inp_output_slot))844 for i, datum in enumerate(self._dump_tensor_data[device_name]):845 node = datum.node_name846 slot = datum.output_slot847 # In some cases (e.g., system clocks with insufficient precision),848 # the upstream and downstream tensors may have identical timestamps, the849 # following check examines this possibility and avoids raising an error if850 # that is the case.851 if not self._satisfied_at_timestamp(852 device_name, pending_inputs[node], datum.timestamp, start_i=i + 1):853 raise ValueError("Causality violated in timing relations of debug "854 "dumps: %s (%d): "855 "these input(s) are not satisfied: %s" %856 (node, datum.timestamp, repr(pending_inputs[node])))857 recipients = self._node_recipients[device_name][node]858 for recipient in recipients:859 recipient_pending_inputs = pending_inputs[recipient]860 if (node, slot) in recipient_pending_inputs:861 if self.node_op_type(recipient) == "Merge":862 # If this is a Merge op, we automatically clear the list because863 # a Merge node only requires one of its two inputs.864 del recipient_pending_inputs[:]865 else:866 del recipient_pending_inputs[867 recipient_pending_inputs.index((node, slot))]868 def _satisfied_at_timestamp(self, device_name, pending, timestamp, start_i=0):869 """Determine whether pending inputs are satisfied at given timestamp.870 Note: This method mutates the input argument "pending".871 Args:872 device_name: (str) device name.873 pending: A list of 2-tuple (node_name, output_slot): the dependencies to874 check.875 timestamp: (int) the timestamp in question.876 start_i: (int) the index in self._dump_tensor_data to start searching for877 the timestamp.878 Returns:879 (bool) Whether all the dependencies in pending are satisfied at the880 timestamp. If pending is empty to begin with, return True.881 """882 if not pending:883 return True884 for datum in self._dump_tensor_data[device_name][start_i:]:885 if datum.timestamp > timestamp:886 break887 if (datum.timestamp == timestamp and888 (datum.node_name, datum.output_slot) in pending):889 pending.remove((datum.node_name, datum.output_slot))890 if not pending:891 return True892 return not pending893 def loaded_partition_graphs(self):894 """Test whether partition graphs have been loaded."""895 return self._partition_graphs is not None896 def partition_graphs(self):897 """Get the partition graphs.898 Returns:899 Partition graphs as a list of GraphDef.900 Raises:901 LookupError: If no partition graphs have been loaded.902 """903 if self._partition_graphs is None:904 raise LookupError("No partition graphs have been loaded.")905 return self._partition_graphs.values()906 @property907 def run_fetches_info(self):908 """Get a str representation of the fetches used in the Session.run() call.909 Returns:910 If the information is available from one `Session.run` call, a `str`911 obtained from `repr(fetches)`.912 If the information is available from multiple `Session.run` calls, a913 `list` of `str` from `repr(fetches)`.914 If the information is not available, `None`.915 """916 output = self._run_fetches_info917 return output[0] if len(output) == 1 else output918 @property919 def run_feed_keys_info(self):920 """Get a str representation of the feed_dict used in the Session.run() call.921 Returns:922 If the information is available from one `Session.run` call, a `str`923 obtained from `repr(feed_dict)`.924 If the information is available from multiple `Session.run` calls, a925 `list` of `str` obtained from `repr(feed_dict)`.926 If the information is not available, `None`.927 """928 output = self._run_feed_keys_info929 return output[0] if len(output) == 1 else output930 def _infer_device_name(self, device_name, node_name):931 if device_name is None:932 if len(self.devices()) == 1:933 return self.devices()[0]934 else:935 if node_name in self._node_devices:936 if len(self._node_devices[node_name]) == 1:937 return list(self._node_devices[node_name])[0]938 else:939 raise ValueError(940 "There are multiple (%d) devices with nodes named '%s' but "941 "device_name is not specified." %942 (len(self._node_devices[node_name]), node_name))943 else:944 raise ValueError("None of the %d devices has a node named '%s'." %945 (len(self._device_names), node_name))946 else:947 return device_name948 def nodes(self, device_name=None):949 """Get a list of all nodes from the partition graphs.950 Args:951 device_name: (`str`) name of device. If there is only one device, this952 argumnet is optional.953 Returns:954 All nodes' names, as a list of str.955 Raises:956 LookupError: If no partition graphs have been loaded.957 ValueError: If there are multiple devices, but device_name is not958 specified.959 """960 if self._partition_graphs is None:961 raise LookupError("No partition graphs have been loaded.")962 if device_name is None:963 if len(self.devices()) == 1:964 device_name = self.devices()[0]965 else:966 raise ValueError(967 "There are multiple (%d) devices, but "968 "device_name is not specified." % len(self.devices()))969 return [node_name for node_name in self._node_inputs[device_name]]970 def node_attributes(self, node_name, device_name=None):971 """Get the attributes of a node.972 Args:973 node_name: Name of the node in question.974 device_name: (`str`) name of the device. If there is only one device or if975 node_name exists on only one device, this argumnet is optional.976 Returns:977 Attributes of the node.978 Raises:979 LookupError: If no partition graphs have been loaded.980 ValueError: If no node named node_name exists.981 """982 if self._partition_graphs is None:983 raise LookupError("No partition graphs have been loaded.")984 device_name = self._infer_device_name(device_name, node_name)985 if node_name in self._node_attributes[device_name]:986 return self._node_attributes[device_name][node_name]987 else:988 raise ValueError("No node named \"%s\" exists on device %s." % (989 node_name, device_name))990 def node_inputs(self, node_name, is_control=False, device_name=None):991 """Get the inputs of given node according to partition graphs.992 Args:993 node_name: Name of the node.994 is_control: (`bool`) Whether control inputs, rather than non-control995 inputs, are to be returned.996 device_name: (`str`) name of the device. If there is only one device or if997 node_name exists on only one device, this argumnet is optional.998 Returns:999 (`list` of `str`) inputs to the node, as a list of node names.1000 Raises:1001 LookupError: If node inputs and control inputs have not been loaded1002 from partition graphs yet.1003 ValueError: If the node does not exist in partition graphs.1004 """1005 if self._partition_graphs is None:1006 raise LookupError(1007 "Node inputs are not loaded from partition graphs yet.")1008 device_name = self._infer_device_name(device_name, node_name)1009 if node_name not in self._node_inputs[device_name]:1010 raise ValueError("Node '%s' does not exist in the partition graph of "1011 "device %s." % (node_name, device_name))1012 if is_control:1013 return self._node_ctrl_inputs[device_name][node_name]1014 else:1015 return self._node_inputs[device_name][node_name]1016 def transitive_inputs(self,1017 node_name,1018 include_control=True,1019 device_name=None):1020 """Get the transitive inputs of given node according to partition graphs.1021 Args:1022 node_name: Name of the node.1023 include_control: Include control inputs (True by default).1024 device_name: (`str`) name of the device. If there is only one device or if1025 node_name exists on only one device, this argumnet is optional.1026 Returns:1027 (`list` of `str`) all transitive inputs to the node, as a list of node1028 names.1029 Raises:1030 LookupError: If node inputs and control inputs have not been loaded1031 from partition graphs yet.1032 ValueError: If the node does not exist in partition graphs.1033 """1034 if self._partition_graphs is None:1035 raise LookupError(1036 "Node inputs are not loaded from partition graphs yet.")1037 device_name = self._infer_device_name(device_name, node_name)1038 if node_name not in self._node_inputs[device_name]:1039 raise ValueError(1040 "Node '%s' does not exist in the partition graph of device %s." %1041 (node_name, device_name))1042 inputs = []1043 # Keep track of visited nodes to avoid infinite loops during input1044 # tracing.1045 visited_nodes = []1046 def trace_inputs(node):1047 """Inner function for recursive tracing of node inputs.1048 The transitive input names are appended to the list captured list1049 "inputs".1050 Args:1051 node: Name of the node, as a str.1052 """1053 node = get_node_name(node)1054 # Stop the tracing at a Merge op, as it is generally impossible to infer1055 # outside the runtime which input to the Merge op is alive.1056 if self._node_op_types[device_name][node] == "Merge":1057 return1058 if node in visited_nodes:1059 return1060 visited_nodes.append(node)1061 for inp in self._node_inputs[device_name][node]:1062 if inp == node_name:1063 continue1064 inputs.append(inp)1065 trace_inputs(inp)1066 if include_control:1067 for ctrl_inp in self._node_ctrl_inputs[device_name][node]:1068 if ctrl_inp == node_name:1069 continue1070 inputs.append(ctrl_inp)1071 trace_inputs(ctrl_inp)1072 trace_inputs(node_name)1073 return inputs1074 def node_recipients(self, node_name, is_control=False, device_name=None):1075 """Get recipient of the given node's output according to partition graphs.1076 Args:1077 node_name: (`str`) name of the node.1078 is_control: (`bool`) whether control outputs, rather than non-control1079 outputs, are to be returned.1080 device_name: (`str`) name of the device. If there is only one device or if1081 node_name exists on only one device, this argumnet is optional.1082 Returns:1083 (`list` of `str`) all inputs to the node, as a list of node names.1084 Raises:1085 LookupError: If node inputs and control inputs have not been loaded1086 from partition graphs yet.1087 ValueError: If the node does not exist in partition graphs.1088 """1089 if self._partition_graphs is None:1090 raise LookupError(1091 "Node recipients are not loaded from partition graphs yet.")1092 device_name = self._infer_device_name(device_name, node_name)1093 if node_name not in self._node_recipients[device_name]:1094 raise ValueError(1095 "Node '%s' does not exist in the partition graph of device %s." %1096 (node_name, device_name))1097 if is_control:1098 return self._node_ctrl_recipients[device_name][node_name]1099 else:1100 return self._node_recipients[device_name][node_name]1101 def devices(self):1102 """Get the list of device names.1103 Returns:1104 (`list` of `str`) names of the devices.1105 """1106 return self._device_names1107 def node_exists(self, node_name, device_name=None):1108 """Test if a node exists in the partition graphs.1109 Args:1110 node_name: (`str`) name of the node to be checked.1111 device_name: optional device name. If None, will search for the node1112 on all available devices. Otherwise, search for the node only on1113 the given device.1114 Returns:1115 A boolean indicating whether the node exists.1116 Raises:1117 LookupError: If no partition graphs have been loaded yet.1118 ValueError: If device_name is specified but cannot be found.1119 """1120 if self._node_inputs is None:1121 raise LookupError(1122 "Nodes have not been loaded from partition graphs yet.")1123 if (device_name is not None) and device_name not in self._node_inputs:1124 raise ValueError(1125 "The specified device_name '%s' cannot be found." % device_name)1126 node_inputs_all_devices = (self._node_inputs if device_name is None1127 else (self._node_inputs[device_name],))1128 return any(node_name in node_inputs_all_devices[dev_name]1129 for dev_name in node_inputs_all_devices)1130 def node_device(self, node_name):1131 """Get the names of the devices that has nodes of the specified name.1132 Args:1133 node_name: (`str`) name of the node.1134 Returns:1135 (`str` or `list` of `str`) name of the device(s) on which the node of the1136 given name is found. Returns a `str` if there is only one such device,1137 otherwise return a `list` of `str`.1138 Raises:1139 LookupError: If node inputs and control inputs have not been loaded1140 from partition graphs yet.1141 ValueError: If the node does not exist in partition graphs.1142 """1143 if self._partition_graphs is None:1144 raise LookupError(1145 "Node devices are not loaded from partition graphs yet.")1146 if node_name not in self._node_devices:1147 raise ValueError("Node '%s' does not exist in partition graphs." %1148 node_name)1149 output = list(self._node_devices[node_name])1150 return output[0] if len(output) == 1 else output1151 def node_op_type(self, node_name, device_name=None):1152 """Get the op type of given node.1153 Args:1154 node_name: (`str`) name of the node.1155 device_name: (`str`) name of the device. If there is only one device or if1156 node_name exists on only one device, this argumnet is optional.1157 Returns:1158 (`str`) op type of the node.1159 Raises:1160 LookupError: If node op types have not been loaded1161 from partition graphs yet.1162 ValueError: If the node does not exist in partition graphs.1163 """1164 if self._partition_graphs is None:1165 raise LookupError(1166 "Node op types are not loaded from partition graphs yet.")1167 device_name = self._infer_device_name(device_name, node_name)1168 if node_name not in self._node_op_types[device_name]:1169 raise ValueError(1170 "Node '%s' does not exist in the partition graph of device '%s'. " %1171 (node_name, device_name))1172 return self._node_op_types[device_name][node_name]1173 def debug_watch_keys(self, node_name, device_name=None):1174 """Get all tensor watch keys of given node according to partition graphs.1175 Args:1176 node_name: (`str`) name of the node.1177 device_name: (`str`) name of the device. If there is only one device or if1178 node_name exists on only one device, this argumnet is optional.1179 Returns:1180 (`list` of `str`) all debug tensor watch keys. Returns an empty list if1181 the node name does not correspond to any debug watch keys.1182 Raises:1183 `LookupError`: If debug watch information has not been loaded from1184 partition graphs yet.1185 """1186 try:1187 device_name = self._infer_device_name(device_name, node_name)1188 except ValueError:1189 return []1190 if node_name not in self._debug_watches[device_name]:1191 return []1192 watch_keys = []1193 for watched_slot in self._debug_watches[device_name][node_name]:1194 debug_ops = self._debug_watches[device_name][node_name][watched_slot]1195 for debug_op in debug_ops:1196 watch_keys.append(1197 _get_tensor_watch_key(node_name, watched_slot, debug_op))1198 return watch_keys1199 def watch_key_to_data(self, debug_watch_key, device_name=None):1200 """Get all `DebugTensorDatum` instances corresponding to a debug watch key.1201 Args:1202 debug_watch_key: (`str`) debug watch key.1203 device_name: (`str`) name of the device. If there is only one device or if1204 the specified debug_watch_key exists on only one device, this argumnet1205 is optional.1206 Returns:1207 A list of `DebugTensorDatum` instances that correspond to the debug watch1208 key. If the watch key does not exist, returns an empty list.1209 Raises:1210 ValueError: If there are multiple devices that have the debug_watch_key,1211 but device_name is not specified.1212 """1213 if device_name is None:1214 matching_device_names = [1215 name for name in self._watch_key_to_datum1216 if debug_watch_key in self._watch_key_to_datum[name]]1217 if not matching_device_names:1218 return []1219 elif len(matching_device_names) == 1:1220 device_name = matching_device_names[0]1221 else:1222 raise ValueError(1223 "The debug watch key '%s' exists on multiple (%d) devices, but "1224 "device name is not specified." %1225 (debug_watch_key, len(matching_device_names)))1226 elif device_name not in self._debug_key_to_datum:1227 raise ValueError(1228 "There is no device named '%s' consisting of debug watch keys." %1229 device_name)1230 return self._watch_key_to_datum[device_name].get(debug_watch_key, [])1231 def find(self, predicate, first_n=0, device_name=None):1232 """Find dumped tensor data by a certain predicate.1233 Args:1234 predicate: A callable that takes two input arguments:1235 ```python1236 def predicate(debug_tensor_datum, tensor):1237 # returns a bool1238 ```1239 where `debug_tensor_datum` is an instance of `DebugTensorDatum`, which1240 carries the metadata, such as the `Tensor`'s node name, output slot1241 timestamp, debug op name, etc.; and `tensor` is the dumped tensor value1242 as a `numpy.ndarray`.1243 first_n: (`int`) return only the first n `DebugTensotDatum` instances (in1244 time order) for which the predicate returns True. To return all the1245 `DebugTensotDatum` instances, let first_n be <= 0.1246 device_name: optional device name.1247 Returns:1248 A list of all `DebugTensorDatum` objects in this `DebugDumpDir` object1249 for which predicate returns True, sorted in ascending order of the1250 timestamp.1251 """1252 matched_data = []1253 for device in (self._dump_tensor_data if device_name is None1254 else (self._dump_tensor_data[device_name],)):1255 for datum in self._dump_tensor_data[device]:1256 if predicate(datum, datum.get_tensor()):1257 matched_data.append(datum)1258 if first_n > 0 and len(matched_data) >= first_n:1259 return matched_data1260 return matched_data1261 def get_tensor_file_paths(self,1262 node_name,1263 output_slot,1264 debug_op,1265 device_name=None):1266 """Get the file paths from a debug-dumped tensor.1267 Args:1268 node_name: (`str`) name of the node that the tensor is produced by.1269 output_slot: (`int`) output slot index of tensor.1270 debug_op: (`str`) name of the debug op.1271 device_name: (`str`) name of the device. If there is only one device or if1272 the specified debug_watch_key exists on only one device, this argumnet1273 is optional.1274 Returns:1275 List of file path(s) loaded. This is a list because each debugged tensor1276 may be dumped multiple times.1277 Raises:1278 WatchKeyDoesNotExistInDebugDumpDirError: If the tensor does not exist in1279 the debug-dump data.1280 """1281 device_name = self._infer_device_name(device_name, node_name)1282 watch_key = _get_tensor_watch_key(node_name, output_slot, debug_op)1283 if watch_key not in self._watch_key_to_datum[device_name]:1284 raise WatchKeyDoesNotExistInDebugDumpDirError(1285 "Watch key \"%s\" does not exist in the debug dump of device %s" %1286 (watch_key, device_name))1287 return [datum.file_path for datum in1288 self._watch_key_to_datum[device_name][watch_key]]1289 def get_tensors(self, node_name, output_slot, debug_op, device_name=None):1290 """Get the tensor value from for a debug-dumped tensor.1291 The tensor may be dumped multiple times in the dump root directory, so a1292 list of tensors (`numpy.ndarray`) is returned.1293 Args:1294 node_name: (`str`) name of the node that the tensor is produced by.1295 output_slot: (`int`) output slot index of tensor.1296 debug_op: (`str`) name of the debug op.1297 device_name: (`str`) name of the device. If there is only one device or if1298 the specified debug_watch_key exists on only one device, this argumnet1299 is optional.1300 Returns:1301 List of tensors (`numpy.ndarray`) loaded from the debug-dump file(s).1302 Raises:1303 WatchKeyDoesNotExistInDebugDumpDirError: If the tensor does not exist in1304 the debug-dump data.1305 """1306 watch_key = _get_tensor_watch_key(node_name, output_slot, debug_op)1307 try:1308 device_name = self._infer_device_name(device_name, node_name)1309 return [datum.get_tensor() for datum in1310 self._watch_key_to_datum[device_name][watch_key]]1311 except (ValueError, KeyError):1312 raise WatchKeyDoesNotExistInDebugDumpDirError(1313 "Watch key \"%s\" does not exist in the debug dump of device %s" %1314 (watch_key, device_name))1315 def get_rel_timestamps(self,1316 node_name,1317 output_slot,1318 debug_op,1319 device_name=None):1320 """Get the relative timestamp from for a debug-dumped tensor.1321 Relative timestamp means (absolute timestamp - `t0`), where `t0` is the1322 absolute timestamp of the first dumped tensor in the dump root. The tensor1323 may be dumped multiple times in the dump root directory, so a list of1324 relative timestamps (`numpy.ndarray`) is returned.1325 Args:1326 node_name: (`str`) name of the node that the tensor is produced by.1327 output_slot: (`int`) output slot index of tensor.1328 debug_op: (`str`) name of the debug op.1329 device_name: (`str`) name of the device. If there is only one device or if1330 the specified debug_watch_key exists on only one device, this argumnet1331 is optional.1332 Returns:1333 (`list` of `int`) list of relative timestamps.1334 Raises:1335 WatchKeyDoesNotExistInDebugDumpDirError: If the tensor watch key does not1336 exist in the debug dump data.1337 """1338 device_name = self._infer_device_name(device_name, node_name)1339 watch_key = _get_tensor_watch_key(node_name, output_slot, debug_op)1340 if watch_key not in self._watch_key_to_datum[device_name]:1341 raise WatchKeyDoesNotExistInDebugDumpDirError(1342 "Watch key \"%s\" does not exist in the debug dump" % watch_key)1343 # TODO(cais): Figure out whether this should be relative to the global t0.1344 return self._watch_key_to_rel_time[device_name][watch_key]1345 def get_dump_sizes_bytes(self,1346 node_name,1347 output_slot,1348 debug_op,1349 device_name=None):1350 """Get the sizes of the dump files for a debug-dumped tensor.1351 Unit of the file size: byte.1352 Args:1353 node_name: (`str`) name of the node that the tensor is produced by.1354 output_slot: (`int`) output slot index of tensor.1355 debug_op: (`str`) name of the debug op.1356 device_name: (`str`) name of the device. If there is only one device or if1357 the specified debug_watch_key exists on only one device, this argumnet1358 is optional.1359 Returns:1360 (`list` of `int`): list of dump file sizes in bytes.1361 Raises:1362 WatchKeyDoesNotExistInDebugDumpDirError: If the tensor watch key does not1363 exist in the debug dump data.1364 """1365 device_name = self._infer_device_name(device_name, node_name)1366 watch_key = _get_tensor_watch_key(node_name, output_slot, debug_op)1367 if watch_key not in self._watch_key_to_datum[device_name]:1368 raise WatchKeyDoesNotExistInDebugDumpDirError(1369 "Watch key \"%s\" does not exist in the debug dump of device %s" %1370 (watch_key, device_name))1371 return self._watch_key_to_dump_size_bytes[device_name][watch_key]1372 def node_traceback(self, element_name):1373 """Try to retrieve the Python traceback of node's construction.1374 Args:1375 element_name: (`str`) Name of a graph element (node or tensor).1376 Returns:1377 (list) The traceback list object as returned by the `extract_trace`1378 method of Python's traceback module.1379 Raises:1380 LookupError: If Python graph is not available for traceback lookup.1381 KeyError: If the node cannot be found in the Python graph loaded.1382 """1383 if self._python_graph is None:1384 raise LookupError("Python graph is not available for traceback lookup")1385 node_name = get_node_name(element_name)1386 if node_name not in self._node_traceback:1387 raise KeyError("Cannot find node \"%s\" in Python graph" % node_name)...
webpack.config.js
Source:webpack.config.js
1const path = require('path');2const webpack = require('webpack');3const childProcess = require('child_process');4const HtmlWebpackPlugin = require('html-webpack-plugin');5const { CleanWebpackPlugin } = require('clean-webpack-plugin');6const MiniCssExtractPlugin = require('mini-css-extract-plugin');7const port = process.env.PORT || 8000;8const env = process.env.NODE_ENV;9const removeNewLine = buffer => buffer.toString().replace('\n', '');10module.exports = {11 mode: 'development',12 entry: {13 main: './src/index.js',14 },15 output: {16 filename: '[name].js',17 path: path.resolve('./dist'),18 },19 module: {20 rules: [21 {22 test: /\.css$/,23 use: [24 process.env.NODE_ENV === 'production'25 ? MiniCssExtractPlugin.loader // íë¡ëì
íê²½26 : 'style-loader', // ê°ë° íê²½27 'css-loader',28 ],29 },30 {31 test: /\.(jpg|png)$/,32 use: {33 loader: 'url-loader', // url ë¡ë를 ì¤ì íë¤34 options: {35 publicPath: './dist/', // file-loaderì ëì¼36 name: '[name].[ext]?[hash]', // file-loaderì ëì¼37 limit: 5000, // 5kb ë¯¸ë§ íì¼ë§ data urlë¡ ì²ë¦¬38 },39 },40 },41 {42 test: /\.less$/,43 use: [44 {45 loader: 'style-loader',46 },47 {48 loader: 'css-loader', // translates CSS into CommonJS49 },50 {51 loader: 'less-loader', // compiles Less to CSS52 options: {53 lessOptions: {54 // If you are using less-loader@5 please spread the lessOptions to options directly55 modifyVars: {56 'primary-color': '#fa43a7',57 'link-color': '#fa43a7',58 'border-radius-base': '5px',59 },60 javascriptEnabled: true,61 },62 },63 },64 ],65 },66 {67 test: /\.(js|jsx)$/,68 exclude: /node_modules/,69 loader: 'babel-loader', // ë°ë²¨ ë¡ë를 ì¶ê°íë¤70 },71 ],72 },73 plugins: [74 new webpack.BannerPlugin({75 banner: `76 Build Date :: ${new Date().toLocaleString()}77 Commit Version :: ${removeNewLine(78 childProcess.execSync('git rev-parse --short HEAD'),79 )}80 Auth.name :: ${removeNewLine(81 childProcess.execSync('git config user.name'),82 )}83 `,84 }),85 new webpack.DefinePlugin({86 test: JSON.stringify('test'),87 'api.domain': JSON.stringify('http://localhost:8000/'),88 }),89 new HtmlWebpackPlugin({90 template: './src/index.html',91 templateParameters: {92 env: env === 'development' ? '(ê°ë°ì©)' : 'íë¡ëì
',93 },94 minify:95 env === 'production'96 ? { collapseWhitespace: true, removeComments: true }97 : false,98 }),99 new CleanWebpackPlugin(),100 ...(env === 'production'101 ? [new MiniCssExtractPlugin({ filename: '[name].css' })]102 : []),103 ],104 devServer: {105 before: (app, server, compiler) => {106 app.get('/ltv/api/prediction', (req, res) => {107 res.json({108 data: {109 week4: 149.12005174160004,110 week1: 128.79898205399513,111 week2: 133.08281889557838,112 week3: 141.10717052221298,113 week5: 138.644366979599,114 week6: 124.10975950956345,115 week7: 133.6972360908985,116 week8: 130.3956716954708,117 },118 total: 1078.9560574889183,119 user: 5280,120 avg: 0.20434773816077997,121 min: 120.2345,122 max: 150.1235,123 ads_ratio: {124 is: 614.8174438476562,125 rv: 53.818878173828125,126 ba: 74.02789306640625,127 },128 });129 });130 app.get('/ltv/api/device-os/analysis', (req, res) => {131 res.json([132 {133 count: 1,134 percentile: 0.03,135 device_os: 'Android 5.0.2',136 },137 {138 count: 6,139 percentile: 0.18,140 device_os: 'Android 5.1.1',141 },142 {143 count: 1,144 percentile: 0.03,145 device_os: 'Android 5.1',146 },147 {148 count: 19,149 percentile: 0.56,150 device_os: 'Android 6.0.1',151 },152 {153 count: 2,154 percentile: 0.06,155 device_os: 'Android 6.0',156 },157 {158 count: 74,159 percentile: 2.19,160 device_os: 'Android 7.0',161 },162 {163 count: 64,164 percentile: 1.89,165 device_os: 'Android 7.1.1',166 },167 {168 count: 6,169 percentile: 0.18,170 device_os: 'Android 7.1.2',171 },172 {173 count: 141,174 percentile: 4.17,175 device_os: 'Android 8.0.0',176 },177 {178 count: 159,179 percentile: 4.7,180 device_os: 'Android 8.1.0',181 },182 {183 count: 885,184 percentile: 26.15,185 device_os: 'Android 9',186 },187 {188 count: 1731,189 percentile: 51.15,190 device_os: 'Android 10',191 },192 {193 count: 295,194 percentile: 8.72,195 device_os: 'Android 11',196 },197 ]);198 });199 app.get('/ltv/api/weekday/analysis/', (req, res) => {200 res.json([201 {202 count: 276,203 percentile: 8.16,204 weekday: 'Monday',205 },206 {207 count: 265,208 percentile: 7.83,209 weekday: 'Tuesday',210 },211 {212 count: 433,213 percentile: 12.8,214 weekday: 'Wednesday',215 },216 {217 count: 706,218 percentile: 20.86,219 weekday: 'Thursday',220 },221 {222 count: 695,223 percentile: 20.54,224 weekday: 'Friday',225 },226 {227 count: 544,228 percentile: 16.08,229 weekday: 'Saturday',230 },231 {232 count: 465,233 percentile: 13.74,234 weekday: 'Sunday',235 },236 ]);237 });238 app.get('/ltv/api/region/analysis/', (req, res) => {239 res.json([240 {241 count: 585,242 percentile: 17.29,243 region: 'California',244 },245 {246 count: 387,247 percentile: 11.44,248 region: 'Texas',249 },250 {251 count: 214,252 percentile: 6.32,253 region: 'Florida',254 },255 {256 count: 184,257 percentile: 5.44,258 region: 'New York',259 },260 {261 count: 128,262 percentile: 3.78,263 region: 'Illinois',264 },265 {266 count: 109,267 percentile: 3.22,268 region: 'North Carolina',269 },270 {271 count: 107,272 percentile: 3.16,273 region: 'Ohio',274 },275 {276 count: 100,277 percentile: 2.96,278 region: 'Georgia',279 },280 {281 count: 98,282 percentile: 2.9,283 region: 'Pennsylvania',284 },285 {286 count: 93,287 percentile: 2.75,288 region: 'Michigan',289 },290 {291 count: 83,292 percentile: 2.45,293 region: 'Washington',294 },295 {296 count: 81,297 percentile: 2.39,298 region: 'Maryland',299 },300 {301 count: 81,302 percentile: 2.39,303 region: 'Tennessee',304 },305 {306 count: 81,307 percentile: 2.39,308 region: 'Arizona',309 },310 {311 count: 74,312 percentile: 2.19,313 region: 'New Jersey',314 },315 {316 count: 69,317 percentile: 2.04,318 region: 'Indiana',319 },320 {321 count: 69,322 percentile: 2.04,323 region: 'Virginia',324 },325 {326 count: 56,327 percentile: 1.65,328 region: 'Colorado',329 },330 {331 count: 51,332 percentile: 1.51,333 region: 'Wisconsin',334 },335 {336 count: 51,337 percentile: 1.51,338 region: 'Massachusetts',339 },340 {341 count: 51,342 percentile: 1.51,343 region: 'Kentucky',344 },345 {346 count: 50,347 percentile: 1.48,348 region: 'Missouri',349 },350 {351 count: 47,352 percentile: 1.39,353 region: 'Oregon',354 },355 {356 count: 46,357 percentile: 1.36,358 region: 'Minnesota',359 },360 {361 count: 42,362 percentile: 1.24,363 region: 'Alabama',364 },365 {366 count: 39,367 percentile: 1.15,368 region: 'South Carolina',369 },370 {371 count: 39,372 percentile: 1.15,373 region: 'Nevada',374 },375 {376 count: 36,377 percentile: 1.06,378 region: 'Connecticut',379 },380 {381 count: 33,382 percentile: 0.98,383 region: 'Louisiana',384 },385 {386 count: 30,387 percentile: 0.89,388 region: 'Arkansas',389 },390 {391 count: 30,392 percentile: 0.89,393 region: 'Utah',394 },395 {396 count: 28,397 percentile: 0.83,398 region: 'Oklahoma',399 },400 {401 count: 27,402 percentile: 0.8,403 region: 'Iowa',404 },405 {406 count: 22,407 percentile: 0.65,408 region: 'Kansas',409 },410 {411 count: 18,412 percentile: 0.53,413 region: 'Mississippi',414 },415 {416 count: 18,417 percentile: 0.53,418 region: 'New Mexico',419 },420 {421 count: 16,422 percentile: 0.47,423 region: 'West Virginia',424 },425 {426 count: 16,427 percentile: 0.47,428 region: 'Nebraska',429 },430 {431 count: 14,432 percentile: 0.41,433 region: 'Maine',434 },435 {436 count: 13,437 percentile: 0.38,438 region: 'New Hampshire',439 },440 {441 count: 13,442 percentile: 0.38,443 region: 'Idaho',444 },445 {446 count: 12,447 percentile: 0.35,448 region: 'Hawaii',449 },450 {451 count: 7,452 percentile: 0.21,453 region: 'Montana',454 },455 {456 count: 7,457 percentile: 0.21,458 region: 'District of Columbia',459 },460 {461 count: 6,462 percentile: 0.18,463 region: 'Rhode Island',464 },465 {466 count: 6,467 percentile: 0.18,468 region: 'Vermont',469 },470 {471 count: 5,472 percentile: 0.15,473 region: 'North Dakota',474 },475 {476 count: 4,477 percentile: 0.12,478 region: 'Delaware',479 },480 {481 count: 3,482 percentile: 0.09,483 region: 'Alaska',484 },485 {486 count: 2,487 percentile: 0.06,488 region: 'Wyoming',489 },490 {491 count: 2,492 percentile: 0.06,493 region: 'South Dakota',494 },495 {496 count: 1,497 percentile: 0.03,498 region: 'Uncertain',499 },500 ]);501 });502 app.get('/ltv/api/device-name/analysis/', (req, res) => {503 res.json([504 {505 count: 116,506 percentile: 3.43,507 device_name: 'Galaxy S9',508 },509 {510 count: 112,511 percentile: 3.31,512 device_name: 'Galaxy A20',513 },514 {515 count: 109,516 percentile: 3.22,517 device_name: 'Stylo 5',518 },519 {520 count: 103,521 percentile: 3.04,522 device_name: 'Galaxy A10e',523 },524 {525 count: 98,526 percentile: 2.9,527 device_name: 'Galaxy S9+',528 },529 {530 count: 90,531 percentile: 2.66,532 device_name: 'Stylo 6',533 },534 {535 count: 85,536 percentile: 2.51,537 device_name: 'K51',538 },539 {540 count: 80,541 percentile: 2.36,542 device_name: 'Galaxy S8+',543 },544 {545 count: 76,546 percentile: 2.25,547 device_name: 'Galaxy S10+',548 },549 {550 count: 72,551 percentile: 2.13,552 device_name: 'Galaxy Note9',553 },554 {555 count: 71,556 percentile: 2.1,557 device_name: 'Galaxy A11',558 },559 {560 count: 69,561 percentile: 2.04,562 device_name: 'Galaxy S8',563 },564 {565 count: 68,566 percentile: 2.01,567 device_name: 'Galaxy A21',568 },569 {570 count: 67,571 percentile: 1.98,572 device_name: 'Galaxy Tab A 10.1 (2019)',573 },574 {575 count: 65,576 percentile: 1.92,577 device_name: 'Galaxy Note8',578 },579 {580 count: 61,581 percentile: 1.8,582 device_name: 'Galaxy S10',583 },584 {585 count: 58,586 percentile: 1.71,587 device_name: 'Galaxy Tab A 8.0 (2019)',588 },589 {590 count: 54,591 percentile: 1.6,592 device_name: 'Galaxy S10e',593 },594 {595 count: 47,596 percentile: 1.39,597 device_name: 'Galaxy J7 (2018)',598 },599 {600 count: 45,601 percentile: 1.33,602 device_name: 'Galaxy A01',603 },604 {605 count: 42,606 percentile: 1.24,607 device_name: 'Galaxy Note10+',608 },609 {610 count: 39,611 percentile: 1.15,612 device_name: 'Galaxy S7',613 },614 {615 count: 37,616 percentile: 1.09,617 device_name: 'K31',618 },619 {620 count: 29,621 percentile: 0.86,622 device_name: 'Galaxy S20+ 5G',623 },624 {625 count: 28,626 percentile: 0.83,627 device_name: 'Moto E6',628 },629 {630 count: 28,631 percentile: 0.83,632 device_name: 'Legacy',633 },634 {635 count: 27,636 percentile: 0.8,637 device_name: 'Galaxy Tab A 8.0 2017',638 },639 {640 count: 27,641 percentile: 0.8,642 device_name: 'Galaxy A71 5G',643 },644 {645 count: 27,646 percentile: 0.8,647 device_name: 'Galaxy A51',648 },649 {650 count: 26,651 percentile: 0.77,652 device_name: 'Galaxy J7 Top',653 },654 {655 count: 25,656 percentile: 0.74,657 device_name: 'Galaxy J7 (2017)',658 },659 {660 count: 24,661 percentile: 0.71,662 device_name: 'G Pad 5 10.1',663 },664 {665 count: 23,666 percentile: 0.68,667 device_name: 'K12 Plus',668 },669 {670 count: 23,671 percentile: 0.68,672 device_name: 'Galaxy A50',673 },674 {675 count: 22,676 percentile: 0.65,677 device_name: 'Galaxy Note20 5G',678 },679 {680 count: 22,681 percentile: 0.65,682 device_name: 'G6',683 },684 {685 count: 22,686 percentile: 0.65,687 device_name: '3V (2019)',688 },689 {690 count: 21,691 percentile: 0.62,692 device_name: 'Galaxy S20 5G',693 },694 {695 count: 21,696 percentile: 0.62,697 device_name: 'Galaxy Tab A 8.4',698 },699 {700 count: 21,701 percentile: 0.62,702 device_name: 'Journey LTE',703 },704 {705 count: 20,706 percentile: 0.59,707 device_name: 'Galaxy Tab A7 10.4 (2020)',708 },709 {710 count: 20,711 percentile: 0.59,712 device_name: 'K30',713 },714 {715 count: 19,716 percentile: 0.56,717 device_name: 'Galaxy Note10',718 },719 {720 count: 19,721 percentile: 0.56,722 device_name: 'Razr D1',723 },724 {725 count: 18,726 percentile: 0.53,727 device_name: 'Galaxy S8 Active',728 },729 {730 count: 17,731 percentile: 0.5,732 device_name: 'Galaxy J2 Core',733 },734 {735 count: 17,736 percentile: 0.5,737 device_name: 'Galaxy S20 FE 5G',738 },739 {740 count: 16,741 percentile: 0.47,742 device_name: 'Galaxy J3 Top',743 },744 {745 count: 16,746 percentile: 0.47,747 device_name: 'Aristo 3',748 },749 {750 count: 15,751 percentile: 0.44,752 device_name: 'Galaxy A51 5G',753 },754 {755 count: 15,756 percentile: 0.44,757 device_name: 'REVVL 4+',758 },759 {760 count: 14,761 percentile: 0.41,762 device_name: 'SmartTab M8',763 },764 {765 count: 14,766 percentile: 0.41,767 device_name: 'Joy Tab',768 },769 {770 count: 14,771 percentile: 0.41,772 device_name: 'Galaxy Tab S5e',773 },774 {775 count: 13,776 percentile: 0.38,777 device_name: 'Galaxy Tab A 10.1',778 },779 {780 count: 13,781 percentile: 0.38,782 device_name: 'Galaxy A6',783 },784 {785 count: 12,786 percentile: 0.35,787 device_name: 'G7 ThinQ',788 },789 {790 count: 12,791 percentile: 0.35,792 device_name: 'Rebel 4',793 },794 {795 count: 11,796 percentile: 0.33,797 device_name: 'Premier Pro Plus',798 },799 {800 count: 11,801 percentile: 0.33,802 device_name: 'Galaxy S7 Edge',803 },804 {805 count: 11,806 percentile: 0.33,807 device_name: 'Galaxy Tab A 8.0 (2018)',808 },809 {810 count: 11,811 percentile: 0.33,812 device_name: 'Galaxy A20s',813 },814 {815 count: 11,816 percentile: 0.33,817 device_name: 'Stylo 3',818 },819 {820 count: 11,821 percentile: 0.33,822 device_name: 'Galaxy J2 Pure',823 },824 {825 count: 11,826 percentile: 0.33,827 device_name: 'Stylo 4',828 },829 {830 count: 10,831 percentile: 0.3,832 device_name: 'Galaxy J7 2015',833 },834 {835 count: 9,836 percentile: 0.27,837 device_name: 'Galaxy Tab E',838 },839 {840 count: 9,841 percentile: 0.27,842 device_name: 'Galaxy Tab S6',843 },844 {845 count: 9,846 percentile: 0.27,847 device_name: 'Fortune 2',848 },849 {850 count: 9,851 percentile: 0.27,852 device_name: 'Galaxy Note 5',853 },854 {855 count: 9,856 percentile: 0.27,857 device_name: 'Galaxy A01 AT&T',858 },859 {860 count: 8,861 percentile: 0.24,862 device_name: 'Galaxy Tab S4',863 },864 {865 count: 8,866 percentile: 0.24,867 device_name: 'Galaxy Note10+ 5G',868 },869 {870 count: 7,871 percentile: 0.21,872 device_name: 'Galaxy Amp Prime 3 2018',873 },874 {875 count: 7,876 percentile: 0.21,877 device_name: 'Q7',878 },879 {880 count: 7,881 percentile: 0.21,882 device_name: 'Galaxy Tab E 8.0',883 },884 {885 count: 7,886 percentile: 0.21,887 device_name: 'Galaxy S20 Ultra 5G',888 },889 {890 count: 7,891 percentile: 0.21,892 device_name: 'Galaxy J3 V 3rd Gen',893 },894 {895 count: 7,896 percentile: 0.21,897 device_name: 'Galaxy Note 20 Ultra 5G',898 },899 {900 count: 7,901 percentile: 0.21,902 device_name: 'Fire HD 10 (2019)',903 },904 {905 count: 6,906 percentile: 0.18,907 device_name: 'V40 ThinQ',908 },909 {910 count: 6,911 percentile: 0.18,912 device_name: 'G8 ThinQ',913 },914 {915 count: 6,916 percentile: 0.18,917 device_name: 'Galaxy J3 Star',918 },919 {920 count: 6,921 percentile: 0.18,922 device_name: 'Galaxy J3 2017',923 },924 {925 count: 6,926 percentile: 0.18,927 device_name: 'X Charge',928 },929 {930 count: 6,931 percentile: 0.18,932 device_name: 'Ovation',933 },934 {935 count: 5,936 percentile: 0.15,937 device_name: 'Galaxy S6',938 },939 {940 count: 5,941 percentile: 0.15,942 device_name: 'Emblem Radiant',943 },944 {945 count: 5,946 percentile: 0.15,947 device_name: 'Tablet Pro',948 },949 {950 count: 5,951 percentile: 0.15,952 device_name: 'Galaxy Tab A',953 },954 {955 count: 5,956 percentile: 0.15,957 device_name: 'V60 ThinQ 5G',958 },959 {960 count: 5,961 percentile: 0.15,962 device_name: 'V36',963 },964 {965 count: 5,966 percentile: 0.15,967 device_name: 'Reflect',968 },969 {970 count: 5,971 percentile: 0.15,972 device_name: 'Galaxy Tab A 8.0 LTE (2019)',973 },974 {975 count: 4,976 percentile: 0.12,977 device_name: 'Insight',978 },979 {980 count: 4,981 percentile: 0.12,982 device_name: 'Fire 7 Tablet',983 },984 {985 count: 4,986 percentile: 0.12,987 device_name: 'J2 Core+',988 },989 {990 count: 4,991 percentile: 0.12,992 device_name: 'Galaxy S21 5G',993 },994 {995 count: 4,996 percentile: 0.12,997 device_name: 'Moto Z2 Force',998 },999 {1000 count: 4,1001 percentile: 0.12,1002 device_name: 'Galaxy Tab A 10.5',1003 },1004 {1005 count: 4,1006 percentile: 0.12,1007 device_name: 'Galaxy Tab S6 Lite',1008 },1009 {1010 count: 4,1011 percentile: 0.12,1012 device_name: 'Galaxy S20 Ultra',1013 },1014 {1015 count: 4,1016 percentile: 0.12,1017 device_name: 'Galaxy J3 Achieve',1018 },1019 {1020 count: 4,1021 percentile: 0.12,1022 device_name: 'Moto G6',1023 },1024 {1025 count: 4,1026 percentile: 0.12,1027 device_name: 'Galaxy A10s',1028 },1029 {1030 count: 4,1031 percentile: 0.12,1032 device_name: 'Phoenix 4',1033 },1034 {1035 count: 4,1036 percentile: 0.12,1037 device_name: '7 Pro',1038 },1039 {1040 count: 3,1041 percentile: 0.09,1042 device_name: 'Blade Spark',1043 },1044 {1045 count: 3,1046 percentile: 0.09,1047 device_name: 'Blade Z Max',1048 },1049 {1050 count: 3,1051 percentile: 0.09,1052 device_name: 'Legacy S',1053 },1054 {1055 count: 3,1056 percentile: 0.09,1057 device_name: 'Blade Vantage 2',1058 },1059 {1060 count: 3,1061 percentile: 0.09,1062 device_name: 'Fire HD 8 (2020)',1063 },1064 {1065 count: 3,1066 percentile: 0.09,1067 device_name: 'Galaxy S6 Edge Plus',1068 },1069 {1070 count: 3,1071 percentile: 0.09,1072 device_name: 'Moto e5 plus',1073 },1074 {1075 count: 3,1076 percentile: 0.09,1077 device_name: 'Galaxy A71',1078 },1079 {1080 count: 3,1081 percentile: 0.09,1082 device_name: 'Raven',1083 },1084 {1085 count: 3,1086 percentile: 0.09,1087 device_name: 'Velvet',1088 },1089 {1090 count: 3,1091 percentile: 0.09,1092 device_name: 'Galaxy A70',1093 },1094 {1095 count: 3,1096 percentile: 0.09,1097 device_name: '7',1098 },1099 {1100 count: 3,1101 percentile: 0.09,1102 device_name: '7T',1103 },1104 {1105 count: 3,1106 percentile: 0.09,1107 device_name: '6T',1108 },1109 {1110 count: 3,1111 percentile: 0.09,1112 device_name: 'Harmony 4',1113 },1114 {1115 count: 2,1116 percentile: 0.06,1117 device_name: 'Galaxy J7 Prime',1118 },1119 {1120 count: 2,1121 percentile: 0.06,1122 device_name: 'Galaxy S6 Active',1123 },1124 {1125 count: 2,1126 percentile: 0.06,1127 device_name: 'Trek 2 HD',1128 },1129 {1130 count: 2,1131 percentile: 0.06,1132 device_name: 'Galaxy S21 Ultra 5G',1133 },1134 {1135 count: 2,1136 percentile: 0.06,1137 device_name: 'Fiesta LTE',1138 },1139 {1140 count: 2,1141 percentile: 0.06,1142 device_name: 'V30+',1143 },1144 {1145 count: 2,1146 percentile: 0.06,1147 device_name: 'Galaxy Tab A 9.7',1148 },1149 {1150 count: 2,1151 percentile: 0.06,1152 device_name: 'Fire HD 10 (2017)',1153 },1154 {1155 count: 2,1156 percentile: 0.06,1157 device_name: 'Tribute Dynasty',1158 },1159 {1160 count: 2,1161 percentile: 0.06,1162 device_name: 'Avalon V',1163 },1164 {1165 count: 2,1166 percentile: 0.06,1167 device_name: 'Galaxy J2 Dash',1168 },1169 {1170 count: 2,1171 percentile: 0.06,1172 device_name: 'Mid8011',1173 },1174 {1175 count: 2,1176 percentile: 0.06,1177 device_name: 'Galaxy Tab E 9.6',1178 },1179 {1180 count: 2,1181 percentile: 0.06,1182 device_name: 'Honor 8X',1183 },1184 {1185 count: 2,1186 percentile: 0.06,1187 device_name: 'Blade Vantage',1188 },1189 {1190 count: 2,1191 percentile: 0.06,1192 device_name: '6',1193 },1194 {1195 count: 2,1196 percentile: 0.06,1197 device_name: 'Fire HD 8 (2018)',1198 },1199 {1200 count: 2,1201 percentile: 0.06,1202 device_name: 'Stylo 3 Plus',1203 },1204 {1205 count: 2,1206 percentile: 0.06,1207 device_name: 'Revvl Plus',1208 },1209 {1210 count: 2,1211 percentile: 0.06,1212 device_name: 'K20 Plus',1213 },1214 {1215 count: 2,1216 percentile: 0.06,1217 device_name: '5T',1218 },1219 {1220 count: 2,1221 percentile: 0.06,1222 device_name: 'V20',1223 },1224 {1225 count: 2,1226 percentile: 0.06,1227 device_name: 'Galaxy A30s',1228 },1229 {1230 count: 2,1231 percentile: 0.06,1232 device_name: 'Moto Z Droid',1233 },1234 {1235 count: 2,1236 percentile: 0.06,1237 device_name: '8',1238 },1239 {1240 count: 2,1241 percentile: 0.06,1242 device_name: 'G Pad F2 8.0',1243 },1244 {1245 count: 2,1246 percentile: 0.06,1247 device_name: 'REVVL 5G',1248 },1249 {1250 count: 2,1251 percentile: 0.06,1252 device_name: 'Galaxy Tab S7 5G',1253 },1254 {1255 count: 2,1256 percentile: 0.06,1257 device_name: 'Galaxy Tab S2 8.0',1258 },1259 {1260 count: 1,1261 percentile: 0.03,1262 device_name: 'Phone',1263 },1264 {1265 count: 1,1266 percentile: 0.03,1267 device_name: 'V30',1268 },1269 {1270 count: 1,1271 percentile: 0.03,1272 device_name: '8 HD tablet',1273 },1274 {1275 count: 1,1276 percentile: 0.03,1277 device_name: 'Harmony',1278 },1279 {1280 count: 1,1281 percentile: 0.03,1282 device_name: 'Galaxy Fold',1283 },1284 {1285 count: 1,1286 percentile: 0.03,1287 device_name: '7 Pro 5G',1288 },1289 {1290 count: 1,1291 percentile: 0.03,1292 device_name: 'Premier Pro',1293 },1294 {1295 count: 1,1296 percentile: 0.03,1297 device_name: 'Mate 20 Pro',1298 },1299 {1300 count: 1,1301 percentile: 0.03,1302 device_name: 'Honor 20 lite',1303 },1304 {1305 count: 1,1306 percentile: 0.03,1307 device_name: 'Tab E10',1308 },1309 {1310 count: 1,1311 percentile: 0.03,1312 device_name: 'G8X ThinQ',1313 },1314 {1315 count: 1,1316 percentile: 0.03,1317 device_name: 'Galaxy Tab S3 9.7',1318 },1319 {1320 count: 1,1321 percentile: 0.03,1322 device_name: 'Galaxy A31',1323 },1324 {1325 count: 1,1326 percentile: 0.03,1327 device_name: 'Galaxy Note20',1328 },1329 {1330 count: 1,1331 percentile: 0.03,1332 device_name: 'Blade A3v',1333 },1334 {1335 count: 1,1336 percentile: 0.03,1337 device_name: 'Ellipsis 10',1338 },1339 {1340 count: 1,1341 percentile: 0.03,1342 device_name: 'Mate 20 X',1343 },1344 {1345 count: 1,1346 percentile: 0.03,1347 device_name: 'G3',1348 },1349 {1350 count: 1,1351 percentile: 0.03,1352 device_name: 'moto e5',1353 },1354 {1355 count: 1,1356 percentile: 0.03,1357 device_name: 'Stylo 2 Plus',1358 },1359 {1360 count: 1,1361 percentile: 0.03,1362 device_name: 'Aristo',1363 },1364 {1365 count: 1,1366 percentile: 0.03,1367 device_name: 'Kindle Fire HD 8 (2017)',1368 },1369 {1370 count: 1,1371 percentile: 0.03,1372 device_name: 'Galaxy A7 (2017)',1373 },1374 {1375 count: 1,1376 percentile: 0.03,1377 device_name: 'MatrixPad S8',1378 },1379 {1380 count: 1,1381 percentile: 0.03,1382 device_name: 'ZMax Pro',1383 },1384 {1385 count: 1,1386 percentile: 0.03,1387 device_name: '1B',1388 },1389 {1390 count: 1,1391 percentile: 0.03,1392 device_name: 'Galaxy On6',1393 },1394 {1395 count: 1,1396 percentile: 0.03,1397 device_name: 'Tetra',1398 },1399 {1400 count: 1,1401 percentile: 0.03,1402 device_name: 'Avid 4',1403 },1404 {1405 count: 1,1406 percentile: 0.03,1407 device_name: 'Galaxy S7 Active',1408 },1409 {1410 count: 1,1411 percentile: 0.03,1412 device_name: 'Galaxy S6 Edge',1413 },1414 {1415 count: 1,1416 percentile: 0.03,1417 device_name: '10 5G',1418 },1419 {1420 count: 1,1421 percentile: 0.03,1422 device_name: 'K8S',1423 },1424 {1425 count: 1,1426 percentile: 0.03,1427 device_name: 'GALAXY SOL 3 (2018)',1428 },1429 {1430 count: 1,1431 percentile: 0.03,1432 device_name: 'A2X',1433 },1434 {1435 count: 1,1436 percentile: 0.03,1437 device_name: 'Galaxy Note 4',1438 },1439 {1440 count: 1,1441 percentile: 0.03,1442 device_name: '5',1443 },1444 {1445 count: 1,1446 percentile: 0.03,1447 device_name: 'Galaxy On5',1448 },1449 {1450 count: 1,1451 percentile: 0.03,1452 device_name: 'K7',1453 },1454 {1455 count: 1,1456 percentile: 0.03,1457 device_name: 'Galaxy A21s',1458 },1459 {1460 count: 1,1461 percentile: 0.03,1462 device_name: 'Galaxy A01 Verizon',1463 },1464 {1465 count: 1,1466 percentile: 0.03,1467 device_name: 'A30 Fierce',1468 },1469 {1470 count: 1,1471 percentile: 0.03,1472 device_name: 'F5 Youth',1473 },1474 {1475 count: 1,1476 percentile: 0.03,1477 device_name: 'Zone 4',1478 },1479 {1480 count: 1,1481 percentile: 0.03,1482 device_name: 'Galaxy View',1483 },1484 {1485 count: 1,1486 percentile: 0.03,1487 device_name: 'A30',1488 },1489 {1490 count: 1,1491 percentile: 0.03,1492 device_name: 'Stylo 4 Plus',1493 },1494 {1495 count: 1,1496 percentile: 0.03,1497 device_name: 'Galaxy J8',1498 },1499 {1500 count: 1,1501 percentile: 0.03,1502 device_name: 'Tab4 8',1503 },1504 {1505 count: 1,1506 percentile: 0.03,1507 device_name: 'Y7 Prime 2019',1508 },1509 {1510 count: 1,1511 percentile: 0.03,1512 device_name: 'Galaxy S21+ 5G',1513 },1514 {1515 count: 1,1516 percentile: 0.03,1517 device_name: 'Ariel-C',1518 },1519 {1520 count: 1,1521 percentile: 0.03,1522 device_name: 'Galaxy A10',1523 },1524 {1525 count: 1,1526 percentile: 0.03,1527 device_name: 'K20 V',1528 },1529 {1530 count: 1,1531 percentile: 0.03,1532 device_name: 'X Power',1533 },1534 {1535 count: 1,1536 percentile: 0.03,1537 device_name: 'Zenpad Z10 ZT500KL',1538 },1539 {1540 count: 1,1541 percentile: 0.03,1542 device_name: 'G Pad X2 8.0 Plus',1543 },1544 {1545 count: 1,1546 percentile: 0.03,1547 device_name: 'MatePad Pro',1548 },1549 {1550 count: 1,1551 percentile: 0.03,1552 device_name: 'DuraForce Pro 2',1553 },1554 {1555 count: 1,1556 percentile: 0.03,1557 device_name: 'Blade Force',1558 },1559 {1560 count: 1,1561 percentile: 0.03,1562 device_name: 'K92 5G',1563 },1564 {1565 count: 1,1566 percentile: 0.03,1567 device_name: 'Ride 2',1568 },1569 {1570 count: 1,1571 percentile: 0.03,1572 device_name: 'Wing 5G',1573 },1574 {1575 count: 1,1576 percentile: 0.03,1577 device_name: 'Xperia XA2 Ultra',1578 },1579 {1580 count: 1,1581 percentile: 0.03,1582 device_name: 'ZFIVE G',1583 },1584 {1585 count: 1,1586 percentile: 0.03,1587 device_name: '3T 8',1588 },1589 {1590 count: 1,1591 percentile: 0.03,1592 device_name: 'Axon 7',1593 },1594 {1595 count: 1,1596 percentile: 0.03,1597 device_name: 'Galileo Pro 11.5',1598 },1599 {1600 count: 1,1601 percentile: 0.03,1602 device_name: 'Honor 8',1603 },1604 {1605 count: 1,1606 percentile: 0.03,1607 device_name: 'Galaxy Tab A 8.0 2018',1608 },1609 {1610 count: 1,1611 percentile: 0.03,1612 device_name: 'A9 (2020)',1613 },1614 {1615 count: 1,1616 percentile: 0.03,1617 device_name: 'Y17',1618 },1619 {1620 count: 1,1621 percentile: 0.03,1622 device_name: 'Ride',1623 },1624 {1625 count: 1,1626 percentile: 0.03,1627 device_name: 'Galaxy Tab A 10.1 2016',1628 },1629 ]);1630 });1631 app.get('/ltv/api/time/analysis/', (req, res) => {1632 res.json([1633 {1634 count: 1232,1635 percentile: 3.64,1636 hour: 0,1637 },1638 {1639 count: 1858,1640 percentile: 5.49,1641 hour: 1,1642 },1643 {1644 count: 2104,1645 percentile: 6.22,1646 hour: 2,1647 },1648 {1649 count: 2223,1650 percentile: 6.57,1651 hour: 3,1652 },1653 {1654 count: 2252,1655 percentile: 6.65,1656 hour: 4,1657 },1658 {1659 count: 2205,1660 percentile: 6.52,1661 hour: 5,1662 },1663 {1664 count: 2404,1665 percentile: 7.1,1666 hour: 6,1667 },1668 {1669 count: 2389,1670 percentile: 7.06,1671 hour: 7,1672 },1673 {1674 count: 2348,1675 percentile: 6.94,1676 hour: 8,1677 },1678 {1679 count: 2113,1680 percentile: 6.24,1681 hour: 9,1682 },1683 {1684 count: 2144,1685 percentile: 6.33,1686 hour: 10,1687 },1688 {1689 count: 2070,1690 percentile: 6.12,1691 hour: 11,1692 },1693 {1694 count: 1761,1695 percentile: 5.2,1696 hour: 12,1697 },1698 {1699 count: 1418,1700 percentile: 4.19,1701 hour: 13,1702 },1703 {1704 count: 1016,1705 percentile: 3,1706 hour: 14,1707 },1708 {1709 count: 592,1710 percentile: 1.75,1711 hour: 15,1712 },1713 {1714 count: 453,1715 percentile: 1.34,1716 hour: 16,1717 },1718 {1719 count: 309,1720 percentile: 0.91,1721 hour: 17,1722 },1723 {1724 count: 271,1725 percentile: 0.8,1726 hour: 18,1727 },1728 {1729 count: 184,1730 percentile: 0.54,1731 hour: 19,1732 },1733 {1734 count: 296,1735 percentile: 0.87,1736 hour: 20,1737 },1738 {1739 count: 498,1740 percentile: 1.47,1741 hour: 21,1742 },1743 {1744 count: 755,1745 percentile: 2.23,1746 hour: 22,1747 },1748 {1749 count: 949,1750 percentile: 2.8,1751 hour: 23,1752 },1753 ]);1754 });1755 },1756 contentBase: path.join(__dirname, 'dist'),1757 publicPath: '/',1758 // host: "dev.domain.com",1759 overlay: true,1760 port,1761 stats: 'errors-only',1762 historyApiFallback: true,1763 },...
moduleconnector.py
Source:moduleconnector.py
1"""@package pymoduleconnector.moduleconnector2Entrypoint functionality.3"""4from .moduleconnectorwrapper import \5 PythonModuleConnector, PyDataRecorder, PyDataReader, PyDataPlayer6from .moduleconnectorwrapper import Bootloader as cBootloader7import socket8import struct9import sys10class Bootloader(cBootloader):11 """ Inherits pymoduleconnector.moduleconnectorwrapper.Bootloader12 13 Examples:14 >>> from pymoduleconnector import Bootloader15 >>> boot = Bootloader("/dev/ttyACM0", log_level=9)16 Open an IP:17 >>> boot = Bootloader("tcp://127.0.0.1:3000")18 """19 def __init__(self, device_name=None, log_level=0):20 if sys.version_info.major == 3:21 if isinstance(device_name, type(b"")):22 device_name = device_name.decode("utf8")23 else:24 if isinstance(device_name, type(u"")):25 device_name = device_name.encode("utf8")26 if not device_name:27 super(Bootloader, self).__init__(log_level)28 elif device_name[:6] == "tcp://":29 dev = device_name[6:].split(":")30 ip = struct.unpack('=L', socket.inet_aton(dev[0]))[0]31 port = socket.htons(int(dev[1]))32 super(Bootloader, self).__init__(ip, port, log_level)33 else:34 super(Bootloader, self).__init__(device_name, log_level)35class ModuleConnector(PythonModuleConnector):36 """ Inherits pymoduleconnector.moduleconnectorwrapper.PythonModuleConnector37 38 @see create_mc39 Examples:40 >>> from pymoduleconnector import ModuleConnector41 >>> mc = ModuleConnector("/dev/ttyACM0", log_level=9)42 >>> x2m200 = mc.get_x2m200()43 >>> print(hex(x2m200.ping()))44 0xaaeeaeeaL45 Open an IP:46 >>> mc = ModuleConnector("tcp://127.0.0.1:3000")47 """48 def __init__(self, device_name=None, log_level=0):49 if sys.version_info.major == 3:50 if isinstance(device_name, type(b"")):51 device_name = device_name.decode("utf8")52 else:53 if isinstance(device_name, type(u"")):54 device_name = device_name.encode("utf8")55 if isinstance(device_name, DataPlayer):56 super(ModuleConnector, self).__init__(device_name, log_level)57 elif not device_name:58 super(ModuleConnector, self).__init__(log_level)59 elif device_name[:6] == "tcp://":60 dev = device_name[6:].split(":")61 ip = struct.unpack('=L', socket.inet_aton(dev[0]))[0]62 port = socket.htons(int(dev[1]))63 super(ModuleConnector, self).__init__(ip, port, log_level)64 elif device_name[:6] == "ish://": 65 super(ModuleConnector, self).__init__("ISH", log_level) 66 else:67 super(ModuleConnector, self).__init__(device_name, log_level)68 # Workaround for scoping issue: if mc object goes out of scope while69 # there's still a reference to the interface, we get dangling pointers.70 def get_x4m200(self):71 x = super(ModuleConnector, self).get_x4m200()72 x._parent = self73 return x74 def get_x4m300(self):75 x = super(ModuleConnector, self).get_x4m300()76 x._parent = self77 return x78 def get_xep(self):79 x = super(ModuleConnector, self).get_xep()80 x._parent = self81 return x82 def get_x2m200(self):83 x = super(ModuleConnector, self).get_x2m200()84 x._parent = self85 return x86class DataRecorder(PyDataRecorder):87 """ Inherits pymoduleconnector.moduleconnectorwrapper.PyDataRecorder88 """89 pass90class DataReader(PyDataReader):91 """ Inherits pymoduleconnector.moduleconnectorwrapper.PyDataReader92 """93 pass94class DataPlayer(PyDataPlayer):95 """ Inherits pymoduleconnector.moduleconnectorwrapper.PyDataPlayer96 """97 pass98from contextlib import contextmanager99import weakref100@contextmanager101def create_mc(*args, **kwargs):102 """Initiate a context managed ModuleConnector object.103 Convenience function to get a context managed ModuleConnector object.104 All references to the object is deleted, thus the serial port connection is105 closed.106 Examples:107 >>> from pymoduleconnector import create_mc108 >>> with create_mc('com11') as mc:109 >>> print(hex(mc.get_x2m200().ping()))110 0xaaeeaeeaL111 """112 mc = ModuleConnector(*args, **kwargs)113 yield weakref.proxy(mc)...
deviceController.js
Source:deviceController.js
1const pool = require("../db");2// get device list3exports.device_list = async (req, res) => {4 try {5 const devicesData = await pool.query("SELECT * FROM devices");6 res.status(200).json(devicesData.rows);7 } catch (error) {8 res.status(500).json(error);9 }10 11};12// get a device13exports.device = async (req, res) => {14 try {15 const { id } = req.params;16 let data = {};17 const deviceData = await pool.query("SELECT * FROM devices where id=$1", [18 id,19 ]);20 data = deviceData;21 res.status(200).json(data.rows[0]);22 } catch (error) {23 res.status(500).json(error);24 }25};26// create device27exports.device_add = async (req, res) => {28 try {29 const { vehicle_id, device_type_id, device_name, is_online, is_active } =30 req.body;31 let maxId = await pool.query("SELECT max(id) FROM devices");32 maxId = maxId.rows[0].max;33 await pool.query(34 `ALTER SEQUENCE devices_seq RESTART WITH ${maxId + 1} INCREMENT BY 1`35 );36 const devicesData = await pool.query(37 "INSERT INTO devices (vehicle_id,device_type_id,device_name,is_online,is_active) VALUES ($1,$2,$3,$4,$5) RETURNING *",38 [vehicle_id, device_type_id, device_name, is_online, is_active]39 );40 res.status(201).json(devicesData.rows[0]);41 } catch (error) {42 res.status(500).json(error);43 }44};45// update device46exports.device_update = async (req, res) => {47 try {48 const { id } = req.params;49 let { vehicle_id, device_type_id, device_name, is_online, is_active } =50 req.body;51 if (!vehicle_id) {52 vehicle_id = await pool.query(53 `select vehicle_id from devices where id=${id}`54 );55 vehicle_id = vehicle_id.rows[0].vehicle_id;56 }57 if (!device_type_id) {58 device_type_id = await pool.query(59 `select device_type_id from devices where id=${id}`60 );61 device_type_id = device_type_id.rows[0].device_type_id;62 }63 if (!device_name) {64 device_name = await pool.query(65 `select device_name from devices where id=${id}`66 );67 device_name = device_name.rows[0].device_name;68 }69 if (!is_online) {70 is_online = await pool.query(71 `select is_online from devices where id=${id}`72 );73 is_online = is_online.rows[0].is_online;74 }75 if (!is_active) {76 is_active = await pool.query(77 `select is_active from devices where id=${id}`78 );79 is_active = is_active.rows[0].is_active;80 }81 const deviceDatas = await pool.query(82 "UPDATE devices SET vehicle_id=$1, device_type_id=$2, device_name=$3, is_online=$4, is_active=$5 where id=$6 RETURNING *",83 [vehicle_id, device_type_id, device_name, is_online, is_active, id]84 );85 res.status(200).json(deviceDatas.rows[0]);86 } catch (error) {87 res.status(500).json(error);88 }89};90// delete device91exports.device_delete = async (req, res) => {92 try {93 const { id } = req.params;94 let data = {};95 const deviceData = await pool.query(96 "DELETE FROM devices where id=$1 RETURNING *",97 [id]98 );99 data = deviceData;100 console.log(data);101 if (data.rowCount != 0) {102 res.status(200).json(data.rows[0]);103 } else {104 res.json({ message: "No data to delete" });105 }106 } catch (error) {107 res.status(500).json(error);108 }...
mock-roomstatus.ts
Source:mock-roomstatus.ts
1import { RoomStatus } from './room';2export const All_Rooms: Array<RoomStatus> = [3 {4 room: {title: "å¨åä¸å¿", run_devices: "8", total_devices: "35", total_person: "45"},5 device_status: [6 {device_name: 'å°æ¶-1#', status: 'åæ¢'},7 {device_name: 'å°æ¶-2#', status: 'è¿è¡'},8 {device_name: 'å°æ¶-3#', status: 'è¿è¡'},9 {device_name: 'å°æ¶-4#', status: 'è¿è¡'},10 {device_name: 'å°æ¶-5#', status: 'åæ¢'},11 {device_name: 'å°æ¶-6#', status: 'åæ¢'},12 {device_name: 'å°æ¶-7#', status: 'è¿è¡'},13 {device_name: 'å°æ¶-8#', status: 'è¿è¡'},14 {device_name: 'å°æ¶-9#', status: 'åæ¢'},15 {device_name: 'å°æ¶-10#', status: 'åæ¢'},16 {device_name: 'å°æ¶-11#', status: 'åæ¢'},17 // {device_name: 'å°æ¶-12#', status: 'è¿è¡'},18 {device_name: 'å°æ¶-13#', status: 'è¿è¡'},19 {device_name: 'å°æ¶-14#', status: 'åæ¢'},20 {device_name: 'å°æ¶-15#', status: 'åæ¢'},21 {device_name: 'å°æ¶-16#', status: 'åæ¢'},22 {device_name: 'å°æ¶-17#', status: 'è¿è¡'},23 {device_name: 'å°æ¶-18#', status: 'è¿è¡'},24 {device_name: 'å°æ¶-19#', status: 'åæ¢'},25 {device_name: 'å°æ¶-20#', status: 'åæ¢'},26 {device_name: 'åæ¥å¨-1#', status: 'åæ¢'},27 {device_name: 'åæ¥å¨-2#', status: 'åæ¢'},28 {device_name: ' åéå¨èä¹
', status: 'åæ¢'},29 ]30 },31 {32 room: {title: "æ°è½æº", run_devices: "4", total_devices: "35", total_person: "45"},33 device_status: [34 {device_name: 'å°æ¶-5#', status: 'è¿è¡'},35 {device_name: 'å°æ¶-6#', status: 'åæ¢'},36 {device_name: 'AVL-1#', status: 'åæ¢'},37 {device_name: 'AVL-2#', status: 'è¿è¡'},38 {device_name: 'AVL-3#', status: 'è¿è¡'},39 {device_name: 'AVL-4#', status: 'è¿è¡'},40 ]41 },42 {43 room: {title: "è¯éªè®¤è¯", run_devices: "2", total_devices: "35", total_person: "45"},44 device_status: [45 {device_name: 'AVL-1#', status: 'åæ¢'},46 {device_name: 'AVL-2#', status: 'è¿è¡'},47 {device_name: 'AVL-3#', status: 'è¿è¡'},48 ]49 },50 {51 room: {title: "NVH", run_devices: "3", total_devices: "35", total_person: "45"},52 device_status: [53 {device_name: 'AVL-8#', status: 'åæ¢'},54 {device_name: 'AVL-9#', status: 'è¿è¡'},55 {device_name: 'AVL-10#', status: 'åæ¢'},56 {device_name: 'hofmann-1#', status: 'è¿è¡'},57 {device_name: 'hofmann-2#', status: 'è¿è¡'},58 {device_name: 'hofmann-3#', status: 'åæ¢'},59 ]60 },...
Using AI Code Generation
1var wpt = require('webpagetest');2var wpt = new WebPageTest('www.webpagetest.org');3var wpt = new WebPageTest('www.webpagetest.org', 'API_KEY');4 if (err) return console.error(err);5 console.log('Test status:', data.statusText);6});7var WebPageTest = require('webpagetest');8var wpt = new WebPageTest('www.webpagetest.org');9var wpt = new WebPageTest('www.webpagetest.org', 'API_KEY');10 if (err) return console.error(err);11 console.log('Test status:', data.statusText);12});13var WebPageTest = require('webpagetest');14var wpt = new WebPageTest('www.webpagetest.org');15var wpt = new WebPageTest('www.webpagetest.org', 'API_KEY');16 if (err) return console.error(err);17 console.log('Test status:', data.statusText);18});19var WebPageTest = require('webpagetest');20var wpt = new WebPageTest('www.webpagetest.org');21var wpt = new WebPageTest('www.webpagetest.org', 'API_KEY');22 if (err) return console.error(err);23 console.log('Test status:', data.statusText);24});25var WebPageTest = require('webpagetest');26var wpt = new WebPageTest('www.webpagetest.org');27var wpt = new WebPageTest('www.webpagetest.org', 'API_KEY');
Using AI Code Generation
1var wpt = require('wpt');2wpt.device('iPhone 6', 'test.js');3var wpt = require('wpt');4wpt.device('iPhone 6 Plus', 'test.js');5var wpt = require('wpt');6wpt.device('iPhone 6s', 'test.js');7var wpt = require('wpt');8wpt.device('iPhone 6s Plus', 'test.js');9var wpt = require('wpt');10wpt.device('iPhone 7', 'test.js');11var wpt = require('wpt');12wpt.device('iPhone 7 Plus', 'test.js');13var wpt = require('wpt');14wpt.device('iPad 2', 'test.js');15var wpt = require('wpt');16wpt.device('iPad Retina', 'test.js');17var wpt = require('wpt');18wpt.device('iPad Air', 'test.js');19var wpt = require('wpt');20wpt.device('iPad Air 2', 'test.js');21var wpt = require('wpt');22wpt.device('iPad Pro', 'test.js');23var wpt = require('wpt');24wpt.device('Nexus 4', 'test.js');25var wpt = require('wpt');26wpt.device('Nexus 5', 'test.js');
Using AI Code Generation
1var wptools = require('wptools');2var wpt = wptools('Albert Einstein');3wpt.device_name(function(err, device_name) {4 if (err) {5 console.log(err);6 } else {7 console.log(device_name);8 }9});
Using AI Code Generation
1var wptb = require('wptb');2var device = new wptb(DEVICE_NAME);3device.open();4device.write('test');5device.close();6var wptb = require('wptb');7var device = new wptb();8device.open();9device.write('test');10device.close();
Using AI Code Generation
1var wpt = require('./wpt.js');2var fs = require('fs');3var device = new wpt('DEVICE_NAME', 'DEVICE_KEY');4 fs.writeFile('test.json', JSON.stringify(data), function(err) {5 if(err) {6 console.log(err);7 } else {8 console.log('The file was saved!');9 }10 });11});12var wpt = require('./wpt.js');13var fs = require('fs');14var device = new wpt('DEVICE_ID', 'DEVICE_KEY');15 fs.writeFile('test.json', JSON.stringify(data), function(err) {16 if(err) {17 console.log(err);18 } else {19 console.log('The file was saved!');20 }21 });22});23var wpt = require('./wpt.js');24var fs = require('fs');25var device = new wpt('DEVICE_LABEL', 'DEVICE_KEY');26 fs.writeFile('test.json', JSON.stringify(data), function(err) {27 if(err) {28 console.log(err);29 } else {30 console.log('The file was saved!');31 }32 });33});34var wpt = require('./wpt.js');35var fs = require('fs');36var device = new wpt('LOCATION', 'DEVICE_KEY');37 fs.writeFile('test.json', JSON.stringify(data), function(err) {38 if(err) {39 console.log(err);40 } else {41 console.log('The file was saved!');42 }43 });44});45var wpt = require('./wpt.js');46var fs = require('fs');47var device = new wpt('LOCATION', 'DEVICE_KEY', 'DEVICE_LABEL');48 fs.writeFile('test.json', JSON.stringify(data), function(err) {49 if(err) {50 console.log(err);51 } else {52 console.log('The file was saved!');
Using AI Code Generation
1var wptb = require('wptb')2var device = wptb.getDevice(DEVICE_NAME)3device.connect(function() {4 device.setLeds(0, 0, 0, 0, 0, 0)5 device.setLeds(1, 0, 0, 0, 0, 0)6 device.setLeds(2, 0, 0, 0, 0, 0)7 device.setLeds(3, 0, 0, 0, 0, 0)8 device.setLeds(4, 0, 0, 0, 0, 0)9 device.setLeds(5, 0, 0, 0, 0, 0)10 device.setLeds(6, 0, 0, 0, 0, 0)11 device.setLeds(7, 0, 0, 0, 0, 0)12})13device.connect(callback)14device.setLeds(index, r, g, b, w, i)15device.connect(function() {
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!