-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathpasha_functor.py
More file actions
65 lines (51 loc) · 2.36 KB
/
Copy pathpasha_functor.py
File metadata and controls
65 lines (51 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from os import getpid
import numpy as np
from . import DataCollection, SourceData, KeyData
from .read_machinery import split_trains
class ExtraDataFunctor:
"""Pasha functor for EXtra-data objects.
This functor wraps an EXtra-data DataCollection, SourceData or
KeyData and performs the map operation over its trains. The kernel
is passed the current train's index in the collection, the train ID
and the data mapping (for DataCollection and SourceData) or data
entry (for KeyData).
"""
def __init__(self, obj):
self.obj = obj
self.n_trains = len(self.obj.train_ids)
# Save PID of parent process where the functor is created to
# close files as appropriately later on, see comment below.
self._parent_pid = getpid()
@classmethod
def wrap(cls, value):
if isinstance(value, (DataCollection, SourceData, KeyData)):
return cls(value)
def split(self, num_workers):
return split_trains(self.n_trains, parts=num_workers)
def iterate(self, share):
subobj = self.obj.select_trains(np.s_[share])
# Older versions of HDF < 1.10.5 are not robust against sharing
# a file descriptor across threads or processes. If running in a
# different process than the functor was initially created in,
# close all file handles inherited from the parent collection to
# force re-opening them again in each child process.
if getpid() != self._parent_pid:
for f in subobj.files:
f.close()
index_it = range(*share.indices(self.n_trains))
if isinstance(subobj, SourceData):
# SourceData has no trains() iterator yet, so simulate it
# ourselves by reconstructing a DataCollection object and
# use its trains() iterator.
dc = DataCollection(
subobj.files, {subobj.source: subobj}, subobj.train_ids,
inc_suspect_trains=subobj.inc_suspect_trains,
is_single_run=True)
data_it = ((train_id, data[subobj.source])
for train_id, data in dc.trains())
else:
# Use the regular trains() iterator for DataCollection and
# KeyData
data_it = subobj.trains()
for index, (train_id, data) in zip(index_it, data_it):
yield index, train_id, data