Skip to content

Commit 9b003f6

Browse files
authored
Merge pull request #2874 from alicevision/dev/tractor_api
[submitter] Add tractor API
2 parents f2f30fc + 46f991f commit 9b003f6

File tree

11 files changed

+615
-34
lines changed

11 files changed

+615
-34
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
.DS_Store
1212
# Windows
1313
Thumbs.db
14+
# vscode
15+
.vscode
1416

1517
# python
1618
*.pyc
@@ -19,6 +21,7 @@ __pycache__
1921

2022
# backup files
2123
*.json
24+
!*Config.json
2225

2326
# datas or personal files
2427
/data

meshroom/core/__init__.py

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,19 @@ def loadClasses(folder: str, packageName: str, classType: type) -> list[type]:
120120
else:
121121
classes.append(p)
122122
except Exception as e:
123-
tb = traceback.extract_tb(e.__traceback__)
124-
last_call = tb[-1]
125-
errors.append(f' * {pluginName} ({type(e).__name__}): {e}\n'
126-
# filename:lineNumber functionName
127-
f'{last_call.filename}:{last_call.lineno} {last_call.name}\n'
128-
# line of code with the error
129-
f'{last_call.line}'
130-
# Full traceback
131-
f'\n{traceback.format_exc()}\n\n'
132-
)
123+
if classType == BaseSubmitter:
124+
logging.warning(f" Could not load submitter {pluginName} from package '{package.__name__}'")
125+
else:
126+
tb = traceback.extract_tb(e.__traceback__)
127+
last_call = tb[-1]
128+
errors.append(f' * {pluginName} ({type(e).__name__}): {e}\n'
129+
# filename:lineNumber functionName
130+
f'{last_call.filename}:{last_call.lineno} {last_call.name}\n'
131+
# line of code with the error
132+
f'{last_call.line}'
133+
# Full traceback
134+
f'\n{traceback.format_exc()}\n\n'
135+
)
133136

134137
if errors:
135138
logging.warning(' The following "{package}" plugins could not be loaded:\n'
@@ -381,14 +384,24 @@ def registerSubmitter(s: BaseSubmitter):
381384
submitters[s.name] = s
382385

383386

384-
def loadSubmitters(folder, packageName):
387+
def loadSubmitters(folder, packageName) -> list[BaseSubmitter]:
385388
if not os.path.isdir(folder):
386389
logging.error(f"Submitters folder '{folder}' does not exist.")
387390
return
388391

389392
return loadClassesSubmitters(folder, packageName)
390393

391394

395+
def loadAllSubmitters(folder) -> list[BaseSubmitter]:
396+
submitters = []
397+
for _, package, ispkg in pkgutil.iter_modules([folder]):
398+
if ispkg:
399+
subs = loadSubmitters(folder, package)
400+
if subs:
401+
submitters.extend(subs)
402+
return submitters
403+
404+
392405
def loadPipelineTemplates(folder: str):
393406
if not os.path.isdir(folder):
394407
logging.error(f"Pipeline templates folder '{folder}' does not exist.")
@@ -409,10 +422,20 @@ def initNodes():
409422

410423

411424
def initSubmitters():
425+
""" Detect and register submitter plugins
426+
Note: Make sure the package name (folder inside the additionalPaths folders)
427+
are unique : so we cannot name them "submitters" because it's already taken
428+
by the submitters package inside meshroom
429+
"""
430+
# Load meshroom default submitters
431+
# Use directly loadSubmitters because we don't want any folder except submitters to be registered
432+
subs = loadSubmitters(meshroomFolder, "submitters")
433+
for sub in subs:
434+
registerSubmitter(sub())
435+
# Load additional submitters
412436
additionalPaths = EnvVar.getList(EnvVar.MESHROOM_SUBMITTERS_PATH)
413-
allSubmittersFolders = [meshroomFolder] + additionalPaths
414-
for folder in allSubmittersFolders:
415-
subs = loadSubmitters(folder, "submitters")
437+
for folder in additionalPaths:
438+
subs = loadAllSubmitters(folder)
416439
for sub in subs:
417440
registerSubmitter(sub())
418441

meshroom/core/graph.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1711,7 +1711,7 @@ def submitGraph(graph, submitter, toNodes=None, submitLabel="{projectName}"):
17111711
res = sub.submit(nodesToProcess, edgesToProcess, graph.filepath, submitLabel=submitLabel)
17121712
if res:
17131713
for node in nodesToProcess:
1714-
node.submit() # update node status
1714+
node.initStatusOnSubmit() # update node status
17151715
except Exception as e:
17161716
logging.error(f"Error on submit : {e}")
17171717

meshroom/core/node.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1320,7 +1320,8 @@ def updateStatusFromCache(self):
13201320
# logging.warning(f"updateStatusFromCache: {self.name}, status: {s} => {self.globalStatus}")
13211321
self.updateOutputAttr()
13221322

1323-
def submit(self, forceCompute=False):
1323+
def initStatusOnSubmit(self, forceCompute=False):
1324+
""" Prepare chunks status when the node is in a graph that was submitted """
13241325
for chunk in self._chunks:
13251326
if forceCompute or chunk.status.status != Status.SUCCESS:
13261327
chunk._status.setNode(self)

meshroom/core/taskManager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ def submit(self, graph, submitter=None, toNodes=None, submitLabel="{projectName}
388388
sub = None
389389
if submitter:
390390
sub = meshroom.core.submitters.get(submitter, None)
391-
elif len(meshroom.core.submitters) == 1:
391+
elif len(meshroom.core.submitters) >= 1:
392392
# if only one submitter available use it
393393
allSubmitters = meshroom.core.submitters.values()
394394
sub = next(iter(allSubmitters)) # retrieve the first element
@@ -434,7 +434,7 @@ def submit(self, graph, submitter=None, toNodes=None, submitLabel="{projectName}
434434
if res:
435435
for node in nodesToProcess:
436436
node.destroyed.connect(lambda obj=None, name=node.name: self.onNodeDestroyed(obj, name))
437-
node.submit() # update node status
437+
node.initStatusOnSubmit() # update node status
438438
self._nodes.update(nodesToProcess)
439439
self._nodesExtern.extend(nodesToProcess)
440440

meshroom/submitters/simpleFarmSubmitter.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
class SimpleFarmSubmitter(BaseSubmitter):
1717

18-
filepath = os.environ.get('SIMPLEFARMCONFIG', os.path.join(currentDir, 'simpleFarmConfig.json'))
18+
filepath = os.environ.get('SIMPLEFARMCONFIG', os.path.join(currentDir, 'tractorConfig.json'))
1919
config = json.load(open(filepath))
2020

2121
reqPackages = []
@@ -82,20 +82,16 @@ def createTask(self, meshroomFile, node):
8282

8383
tags['nbFrames'] = nbFrames
8484
tags['prod'] = self.prod
85-
allRequirements = list()
86-
allRequirements.extend(self.config['CPU'].get(node.nodeDesc.cpu.name, []))
87-
allRequirements.extend(self.config['RAM'].get(node.nodeDesc.ram.name, []))
88-
allRequirements.extend(self.config['GPU'].get(node.nodeDesc.gpu.name, []))
85+
allRequirements = set()
86+
allRequirements.update(self.config['CPU'].get(node.nodeDesc.cpu.name, []))
87+
allRequirements.update(self.config['RAM'].get(node.nodeDesc.ram.name, []))
88+
allRequirements.update(self.config['GPU'].get(node.nodeDesc.gpu.name, []))
8989

90+
executable = 'meshroom_compute' if self.reqPackages else os.path.join(binDir, 'meshroom_compute')
91+
taskCommand = f"{executable} --node {node.name} \"{meshroomFile}\" {parallelArgs} --extern"
9092
task = simpleFarm.Task(
91-
name=node.name,
92-
command='{exe} --node {nodeName} "{meshroomFile}" {parallelArgs} --extern'.format(
93-
exe='meshroom_compute' if self.reqPackages else os.path.join(binDir, 'meshroom_compute'),
94-
nodeName=node.name, meshroomFile=meshroomFile, parallelArgs=parallelArgs),
95-
tags=tags,
96-
rezPackages=self.reqPackages,
97-
requirements={'service': str(','.join(allRequirements))},
98-
**arguments)
93+
name=node.name, command=taskCommand, tags=tags, rezPackages=self.reqPackages,
94+
requirements={'service': str(','.join(allRequirements))}, **arguments)
9995
return task
10096

10197
def submit(self, nodes, edges, filepath, submitLabel="{projectName}"):

meshroom/submitters/simpleFarmConfig.json renamed to meshroom/submitters/tractorConfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"BASE": ["mikrosRender", "!ld7"],
2+
"BASE": ["mikrosRender"],
33
"CPU": {
44
"NONE": [],
55
"NORMAL": ["mikrosRender"],
@@ -16,3 +16,4 @@
1616
"INTENSIVE": ["cuda16G"]
1717
}
1818
}
19+

0 commit comments

Comments
 (0)