def header(self): """The header associated with the BQM.""" # lazy construction try: return self._header except AttributeError: pass bqm = self.bqm prefix = BQM_MAGIC_PREFIX version = bytes(self.version) if self.ignore_labels: index_labeled = True else: index_labeled = all(i == v for i, v in enumerate(bqm.variables)) if index_labeled: # if we're index labelled, then the variables section should be # empty self._variables_section = bytes() data = dict( shape=bqm.shape, dtype=bqm.dtype.name, itype=bqm.itype.name, ntype=bqm.ntype.name, vartype=bqm.vartype.name, type=type(bqm).__name__, ) if self._variables_in_header: data.update( variables=list(iter_serialize_variables(bqm.variables))) else: data.update(variables=not index_labeled) header_data = json.dumps(data, sort_keys=True).encode('ascii') header_data += b'\n' # whole header length should be divisible by 16 header_data += b' ' * ( 16 - (len(prefix) + len(version) + 4 + len(header_data)) % 16) header_len = np.dtype('<u4').type(len(header_data)).tobytes() self._header = header = prefix + version + header_len + header_data assert len(header) % 16 == 0 # sanity check return self.header
def to_serializable(self): variables = list(iter_serialize_variables(self.keys())) variables.sort(key=lambda x: str(x)) num_variables = len(variables) chains = [] for v in variables: chain = list(iter_serialize_variables(self[v])) chain.sort(key=lambda x: str(x)) chains.append(chain) doc = { # metadata "type": 'Embedding', # embedding "num_variables": num_variables, "variable_labels": variables, "chains": chains, "properties": self.properties } return doc
def to_serializable(self, use_bytes=False, bias_dtype=np.float32, bytes_type=bytes): """Convert the binary quadratic model to a serializable object. Args: use_bytes (bool, optional, default=False): If True, a compact representation representing the biases as bytes is used. Uses :func:`~numpy.ndarray.tobytes`. bias_dtype (data-type, optional, default=numpy.float32): If `use_bytes` is True, this :class:`~numpy.dtype` will be used to represent the bias values in the serialized format. bytes_type (class, optional, default=bytes): This class will be used to wrap the bytes objects in the serialization if `use_bytes` is true. Returns: dict: An object that can be serialized. Examples: Encode using JSON >>> import json ... >>> bqm = dimod.BinaryQuadraticModel({'a': -1.0, 'b': 1.0}, {('a', 'b'): -1.0}, 0.0, dimod.SPIN) >>> s = json.dumps(bqm.to_serializable()) Encode using BSON_ >>> import bson ... >>> bqm = dimod.BinaryQuadraticModel({'a': -1.0, 'b': 1.0}, {('a', 'b'): -1.0}, 0.0, dimod.SPIN) >>> doc = bqm.to_serializable(use_bytes=True) >>> b = bson.BSON.encode(doc) # doctest: +SKIP See also: :meth:`~.BinaryQuadraticModel.from_serializable` :func:`json.dumps`, :func:`json.dump` JSON encoding functions :meth:`bson.BSON.encode` BSON encoding method .. _BSON: http://bsonspec.org/ """ from dimod.package_info import __version__ schema_version = "3.0.0" variables = list(iter_serialize_variables(self.variables)) try: variables.sort() except TypeError: # cannot unlike types in py3 pass num_variables = len(variables) # when doing byte encoding we can use less space depending on the # total number of variables index_dtype = np.uint16 if num_variables <= 2**16 else np.uint32 ldata, (irow, icol, qdata), offset = self.to_numpy_vectors( dtype=bias_dtype, index_dtype=index_dtype, sort_indices=True, # to make it deterministic for the order variable_order=variables) num_interactions = len(irow) doc = { # metadata "type": type(self).__name__, "version": { "bqm_schema": schema_version }, "use_bytes": bool(use_bytes), "index_type": np.dtype(index_dtype).name, "bias_type": np.dtype(bias_dtype).name, # bqm "num_variables": num_variables, "num_interactions": num_interactions, "variable_labels": variables, "variable_type": self.vartype.name, "offset": float(offset), "info": serialize_ndarrays(self.info, use_bytes=use_bytes, bytes_type=bytes_type), } if use_bytes: # these are vectors so don't need to specify byte-order doc.update({ 'linear_biases': bytes_type(ldata.tobytes()), 'quadratic_biases': bytes_type(qdata.tobytes()), 'quadratic_head': bytes_type(irow.tobytes()), 'quadratic_tail': bytes_type(icol.tobytes()) }) else: doc.update({ 'linear_biases': ldata.tolist(), 'quadratic_biases': qdata.tolist(), 'quadratic_head': irow.tolist(), 'quadratic_tail': icol.tolist() }) return doc
def dump_data(self): serializable = list(iter_serialize_variables(self.variables)) return json.dumps(serializable).encode('ascii')