Skip to content

Commit 2482ab2

Browse files
Spaceenterbabbush
authored andcommitted
Use marshal for save/load operators to improve performance (#124)
* Use marshal for save/load operators to improve performance * ... * make it work with python3
1 parent ffb98da commit 2482ab2

File tree

1 file changed

+21
-25
lines changed

1 file changed

+21
-25
lines changed

src/fermilib/utils/_operator_utils.py

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
"""This module provides generic tools for classes in ops/"""
1414
from __future__ import absolute_import
1515

16-
import h5py
17-
import json
16+
import marshal
1817
import numpy
1918
import os
2019
import time
2120

2221
from fermilib.config import *
2322
from fermilib.ops import *
23+
from future.builtins.iterators import map, zip
2424

2525
from projectq.ops import QubitOperator
2626

@@ -123,11 +123,11 @@ def commutator(operator_a, operator_b):
123123

124124

125125
def save_operator(operator, file_name=None, data_directory=None):
126-
"""Save FermionOperator or QubitOperator to hdf5 file.
126+
"""Save FermionOperator or QubitOperator to file.
127127
128128
Args:
129129
operator: An instance of FermionOperator or QubitOperator.
130-
file_name: The name of the saved hdf5 file.
130+
file_name: The name of the saved file.
131131
data_directory: Optional data directory to change from default data
132132
directory specified in config file.
133133
@@ -151,19 +151,18 @@ def save_operator(operator, file_name=None, data_directory=None):
151151
else:
152152
raise TypeError('Operator of invalid type.')
153153

154-
with h5py.File(file_path, 'w') as f:
155-
f['operator_type'] = numpy.string_(operator_type)
156-
f['operator_terms'] = numpy.string_(json.dumps(
157-
[{'k': k, 'r': v.real, 'i': v.imag}
158-
for k, v in operator.terms.items()],
159-
ensure_ascii=False).encode('utf8'))
154+
tm = operator.terms
155+
with open(file_path, 'wb') as f:
156+
marshal.dump((operator_type, dict(zip(tm.keys(),
157+
map(complex, tm.values())))), f)
158+
f.close()
160159

161160

162161
def load_operator(file_name=None, data_directory=None):
163-
"""Load FermionOperator or QubitOperator from hdf5 file.
162+
"""Load FermionOperator or QubitOperator from file.
164163
165164
Args:
166-
file_name: The name of the saved hdf5 file.
165+
file_name: The name of the saved file.
167166
data_directory: Optional data directory to change from default data
168167
directory specified in config file.
169168
@@ -175,33 +174,30 @@ def load_operator(file_name=None, data_directory=None):
175174
"""
176175
file_path = get_file_path(file_name, data_directory)
177176

178-
with h5py.File(file_path, 'r') as f:
179-
operator_type = f['operator_type'][...].tobytes().decode('utf-8')
180-
operator_terms = json.loads(
181-
f['operator_terms'][...].tobytes().decode('utf-8'))
177+
with open(file_path, 'rb') as f:
178+
data = marshal.load(f)
179+
operator_type = data[0]
180+
operator_terms = data[1]
182181

183182
if operator_type == 'FermionOperator':
184183
operator = FermionOperator()
185184
for term in operator_terms:
186-
operator += FermionOperator(
187-
tuple(tuple(x) for x in term['k']), term['r'] + term['i'] * 1j)
185+
operator += FermionOperator(term, operator_terms[term])
188186
elif operator_type == 'QubitOperator':
189187
operator = QubitOperator()
190188
for term in operator_terms:
191-
operator += QubitOperator(
192-
tuple((x[0], str(x[1])) for x in term['k']),
193-
term['r'] + term['i'] * 1j)
189+
operator += QubitOperator(term, operator_terms[term])
194190
else:
195191
raise TypeError('Operator of invalid type.')
196192

197193
return operator
198194

199195

200196
def get_file_path(file_name, data_directory):
201-
"""Compute file_path for the hdf5 file that stores operator.
197+
"""Compute file_path for the file that stores operator.
202198
203199
Args:
204-
file_name: The name of the saved hdf5 file.
200+
file_name: The name of the saved file.
205201
data_directory: Optional data directory to change from default data
206202
directory specified in config file.
207203
@@ -212,8 +208,8 @@ def get_file_path(file_name, data_directory):
212208
OperatorUtilsError: File name is not provided.
213209
"""
214210
if file_name:
215-
if file_name[-5:] != '.hdf5':
216-
file_name = file_name + ".hdf5"
211+
if file_name[-5:] != '.data':
212+
file_name = file_name + ".data"
217213
else:
218214
raise OperatorUtilsError("File name is not provided.")
219215

0 commit comments

Comments
 (0)