Skip to content

Commit 2df2995

Browse files
gchalumpfacebook-github-bot
authored andcommitted
Add Manifold wrapper (attemp 2) (pytorch#4410)
Summary: X-link: facebookresearch/FBGEMM#1481 Pull Request resolved: pytorch#4410 ## Summary This diff represents a second attempt to integrate a Manifold wrapper to facilitate reporter integration with the TBE forward operation, as referenced in D73927918. which failed a [test](https://www.internalfb.com/intern/test/281475120056413)where it expected all dependencies to be purely in Python. - manifold_cli python library actually relies on C++ manifold cpp library, which breaks certain python packages/tests that cannot have a manfiold C++ dependency - the workaround is to use manifold C++ and have all the dependency built (wrapped as Torch class) with fbgemm_gpu. However, this causes issues that led to S532997. - D76186007 updates `fb:utils` to use have manifold cpp dependency. - many models/workflows use different packages for frontend (e.g., python) and backend (e.g., C++) - this causes issue for frontend package that already include D76186007 but use backend package that does not include. D76186007 - fb:utils (in frontend package), expects this manifold cpp source code. - backend packages does not contains this source code - hence, it fails with ```libdeeplearning_fbgemm_fbgemm_gpu_fb_utils_cpp.so: cannot open shared object file: No such file or directory``` This diff ensures all the changes are built as separate targets, which are not included in any existing targets/usage. We will carefully make changes to switch to use this targets to ensure backward compatibility in the next diff. Reviewed By: spcyppt Differential Revision: D77241003 fbshipit-source-id: c60a1ef75c4d7404e197d349f34debcedfee3d95
1 parent c70539a commit 2df2995

File tree

2 files changed

+109
-8
lines changed

2 files changed

+109
-8
lines changed

fbgemm_gpu/fbgemm_gpu/utils/filestore.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,53 @@ def exists(self, path: str) -> bool:
155155
True if file exists, False otherwise.
156156
"""
157157
filepath = f"{self.bucket}/{path}"
158-
return os.path.isfile(filepath)
158+
return os.path.exists(filepath)
159+
160+
def create_directory(self, path: str) -> "FileStore":
161+
"""
162+
Creates a directory in the file store.
163+
164+
Args:
165+
path (str): The path of the node or symlink to a directory (relative
166+
to `self.bucket`) to be created.
167+
168+
Returns:
169+
self. This allows for method-chaining.
170+
"""
171+
filepath = f"{self.bucket}/{path}"
172+
event = f"creating directory {filepath}"
173+
logger.info(f"FileStore: {event}")
174+
175+
try:
176+
if not os.path.exists(filepath):
177+
os.makedirs(filepath, exist_ok=True)
178+
except Exception as e:
179+
logger.error(f"FileStore: exception occurred when {event}: {e}")
180+
raise e
181+
182+
return self
183+
184+
def remove_directory(self, path: str) -> "FileStore":
185+
"""
186+
Removes a directory from the file store.
187+
188+
Args:
189+
path (str): The path of the node or symlink to a directory (relative
190+
to `self.bucket`) to be removed.
191+
192+
Returns:
193+
self. This allows for method-chaining.
194+
"""
195+
filepath = f"{self.bucket}/{path}"
196+
event = f"deleting {filepath}"
197+
logger.info(f"FileStore: {event}")
198+
199+
try:
200+
if os.path.isdir(filepath):
201+
os.rmdir(filepath)
202+
203+
except Exception as e:
204+
logger.error(f"Manifold: exception occurred when {event}: {e}")
205+
raise e
206+
207+
return self

fbgemm_gpu/test/utils/filestore_test.py

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,41 @@ def _test_filestore_readwrite(
6060
store.remove(path)
6161
assert not store.exists(path), f"{path} is not removed"
6262

63+
def _test_filestore_directory(
64+
self,
65+
# pyre-fixme[2]
66+
store, # FileStore
67+
root_dir: Optional[str] = None,
68+
) -> None:
69+
"""
70+
Generic FileStore routines to test creating and removing directories
71+
72+
Args:
73+
store (FileStore): The FileStore to test
74+
root_dir (str): The root directory to create
75+
"""
76+
if root_dir is not None:
77+
root_dir += "/"
78+
else:
79+
root_dir = ""
80+
81+
dir1 = f"{''.join(random.choices(string.ascii_letters, k=15))}"
82+
dir2 = f"{''.join(random.choices(string.ascii_letters, k=15))}"
83+
84+
store.create_directory(f"{root_dir}{dir1}/{dir2}")
85+
assert store.exists(
86+
f"{root_dir}{dir1}/{dir2}"
87+
), f"Failed creating directories /{dir1}/{dir2}, directoies does not exist"
88+
89+
store.remove_directory(f"{root_dir}{dir1}/{dir2}")
90+
assert not store.exists(
91+
f"{root_dir}{dir1}/{dir2}"
92+
), f"Failed removing directories /{dir1}/{dir2}, directory still exists"
93+
store.remove_directory(f"{root_dir}{dir1}")
94+
assert not store.exists(
95+
f"{root_dir}{dir1}"
96+
), f"Failed removing directories /{dir1}, directory still exists"
97+
6398
def test_filestore_oss_bad_bucket(self) -> None:
6499
"""
65100
Test that OSS FileStore raises ValueError when an invalid bucket is provided
@@ -104,12 +139,20 @@ def test_filestore_oss_file(self) -> None:
104139

105140
self._test_filestore_readwrite(FileStore("/tmp"), Path(infile.name))
106141

142+
def test_filestore_oss_directory(self) -> None:
143+
"""
144+
Test that OSS FileStore can create and remove directories
145+
"""
146+
from fbgemm_gpu.utils import FileStore
147+
148+
self._test_filestore_directory(FileStore("/tmp"))
149+
107150
@unittest.skipIf(open_source, "Test does not apply to OSS")
108151
def test_filestore_fb_bad_bucket(self) -> None:
109152
"""
110153
Test that FB FileStore raises ValueError when an invalid bucket is provided
111154
"""
112-
from fbgemm_gpu.fb.utils import FileStore
155+
from fbgemm_gpu.fb.utils.manifold_wrapper import FileStore
113156

114157
self.assertRaises(
115158
ValueError, FileStore, "".join(random.choices(string.ascii_letters, k=15))
@@ -120,33 +163,33 @@ def test_filestore_fb_binaryio(self) -> None:
120163
"""
121164
Test that FB FileStore can read and write binary data
122165
"""
123-
from fbgemm_gpu.fb.utils import FileStore
166+
from fbgemm_gpu.fb.utils.manifold_wrapper import FileStore
124167

125168
self._test_filestore_readwrite(
126169
FileStore("tlparse_reports"),
127170
io.BytesIO("".join(random.choices(string.ascii_letters, k=128)).encode()),
128-
f"tree/{''.join(random.choices(string.ascii_letters, k=15))}.unittest",
171+
f"tree/unit_tests/{''.join(random.choices(string.ascii_letters, k=15))}.unittest",
129172
)
130173

131174
@unittest.skipIf(open_source, "Test does not apply to OSS")
132175
def test_filestore_fb_tensor(self) -> None:
133176
"""
134177
Test that FB FileStore can read and write tensors
135178
"""
136-
from fbgemm_gpu.fb.utils import FileStore
179+
from fbgemm_gpu.fb.utils.manifold_wrapper import FileStore
137180

138181
self._test_filestore_readwrite(
139182
FileStore("tlparse_reports"),
140183
torch.rand((random.randint(100, 1000), random.randint(100, 1000))),
141-
f"tree/{''.join(random.choices(string.ascii_letters, k=15))}.unittest",
184+
f"tree/unit_tests/{''.join(random.choices(string.ascii_letters, k=15))}.unittest",
142185
)
143186

144187
@unittest.skipIf(open_source, "Test does not apply to OSS")
145188
def test_filestore_fb_file(self) -> None:
146189
"""
147190
Test that FB FileStore can read and write files
148191
"""
149-
from fbgemm_gpu.fb.utils import FileStore
192+
from fbgemm_gpu.fb.utils.manifold_wrapper import FileStore
150193

151194
input = torch.rand((random.randint(100, 1000), random.randint(100, 1000)))
152195
infile = tempfile.NamedTemporaryFile()
@@ -155,5 +198,14 @@ def test_filestore_fb_file(self) -> None:
155198
self._test_filestore_readwrite(
156199
FileStore("tlparse_reports"),
157200
Path(infile.name),
158-
f"tree/{''.join(random.choices(string.ascii_letters, k=15))}.unittest",
201+
f"tree/unit_tests/{''.join(random.choices(string.ascii_letters, k=15))}.unittest",
159202
)
203+
204+
@unittest.skipIf(open_source, "Test does not apply to OSS")
205+
def test_filestore_fb_directory(self) -> None:
206+
"""
207+
Test that FB FileStore can create and remove directories
208+
"""
209+
from fbgemm_gpu.fb.utils.manifold_wrapper import FileStore
210+
211+
self._test_filestore_directory(FileStore("tlparse_reports"), "tree/unit_tests")

0 commit comments

Comments
 (0)