Skip to content

Commit

Permalink
Only support scalars and numpy arrays in HDF5 output. Update document…
Browse files Browse the repository at this point in the history
…ation. Closes #145
sbourdeauducq committed Oct 28, 2015
1 parent ec328cf commit 40b4129
Showing 3 changed files with 27 additions and 30 deletions.
10 changes: 8 additions & 2 deletions artiq/language/environment.py
Original file line number Diff line number Diff line change
@@ -208,9 +208,15 @@ def set_dataset(self, key, value,
broadcast=False, persist=False, save=True):
"""Sets the contents and handling modes of a dataset.
If the dataset is broadcasted, it must be PYON-serializable.
If the dataset is saved, it must be a scalar (``bool``, ``int``,
``float`` or NumPy scalar) or a NumPy array.
:param broadcast: the data is sent in real-time to the master, which
dispatches it. Returns a Notifier that can be used to mutate the dataset.
:param persist: the master should store the data on-disk. Implies broadcast.
dispatches it. Returns a Notifier that can be used to mutate the
dataset.
:param persist: the master should store the data on-disk. Implies
broadcast.
:param save: the data is saved into the local storage of the current
run (archived as a HDF5 file).
"""
31 changes: 15 additions & 16 deletions artiq/master/worker_db.py
Original file line number Diff line number Diff line change
@@ -138,21 +138,17 @@ def get_last_rid():

def result_dict_to_hdf5(f, rd):
for name, data in rd.items():
if isinstance(data, list):
el_ty = type(data[0])
for d in data:
if type(d) != el_ty:
raise TypeError("All list elements must have the same"
" type for HDF5 output")
try:
el_ty_h5 = _type_to_hdf5[el_ty]
except KeyError:
raise TypeError("List element type {} is not supported for"
" HDF5 output".format(el_ty))
dataset = f.create_dataset(name, (len(data), ), el_ty_h5)
dataset[:] = data
elif isinstance(data, np.ndarray):
f.create_dataset(name, data=data)
flag = None
# beware: isinstance(True/False, int) == True
if isinstance(data, bool):
data = np.int8(data)
flag = "py_bool"
elif isinstance(data, int):
data = np.int64(data)
flag = "py_int"

if isinstance(data, np.ndarray):
dataset = f.create_dataset(name, data=data)
else:
ty = type(data)
if ty is str:
@@ -163,10 +159,13 @@ def result_dict_to_hdf5(f, rd):
ty_h5 = _type_to_hdf5[ty]
except KeyError:
raise TypeError("Type {} is not supported for HDF5 output"
.format(ty))
.format(ty)) from None
dataset = f.create_dataset(name, (), ty_h5)
dataset[()] = data

if flag is not None:
dataset.attrs[flag] = np.int8(1)


class DatasetManager:
def __init__(self, ddb):
16 changes: 4 additions & 12 deletions artiq/test/h5types.py
Original file line number Diff line number Diff line change
@@ -9,25 +9,17 @@
class TypesCase(unittest.TestCase):
def test_types(self):
d = {
"bool": True,
"int": 42,
"float": 42.0,
"string": "abcdef",

"intlist": [1, 2, 3],
"floatlist": [1.0, 2.0, 3.0]
}

for size in 8, 16, 32, 64:
signed = getattr(np, "int" + str(size))
unsigned = getattr(np, "uint" + str(size))
d["i"+str(size)] = signed(42)
d["u"+str(size)] = unsigned(42)
d["i{}list".format(size)] = [signed(x) for x in range(3)]
d["u{}list".format(size)] = [unsigned(x) for x in range(3)]
d["i"+str(size)] = getattr(np, "int" + str(size))(42)
d["u"+str(size)] = getattr(np, "uint" + str(size))(42)
for size in 16, 32, 64:
ty = getattr(np, "float" + str(size))
d["f"+str(size)] = ty(42)
d["f{}list".format(size)] = [ty(x) for x in range(3)]
d["f"+str(size)] = getattr(np, "float" + str(size))(42)

with h5py.File("h5types.h5", "w") as f:
result_dict_to_hdf5(f, d)

0 comments on commit 40b4129

Please sign in to comment.