Skip to content

Commit aa18d62

Browse files
authored
Merge pull request #259 from buildingSMART/tfk-memory-optimizations-2
Max outcomes per rule in validate
2 parents dc4edce + 9fdded0 commit aa18d62

File tree

3 files changed

+54
-16
lines changed

3 files changed

+54
-16
lines changed

backend/apps/ifc_validation/checks/check_gherkin.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
except:
88
import apps.ifc_validation.checks.ifc_gherkin_rules as gherkin_rules # tests
99

10-
def perform(ifc_fn, task_id, rule_type, verbose, purepythonparser=False):
10+
def perform(ifc_fn, task_id, rule_type, max_outcomes: int, verbose, purepythonparser=False):
1111

1212
try:
1313

1414
gherkin_rule_type = gherkin_rules.RuleType[rule_type]
1515
rules_run = gherkin_rules.run(
1616
filename=ifc_fn,
1717
rule_type=gherkin_rule_type,
18+
max_outcomes=max_outcomes,
1819
task_id=task_id,
1920
with_console_output=verbose,
2021
purepythonparser=purepythonparser
@@ -34,6 +35,7 @@ def perform(ifc_fn, task_id, rule_type, verbose, purepythonparser=False):
3435
parser.add_argument("--file-name", "-f", type=str, required=True)
3536
parser.add_argument("--task-id", "-t", type=int, required=False, default=None)
3637
parser.add_argument("--rule-type", "-r", type=str, default='ALL')
38+
parser.add_argument('--max-outcomes', "-m", type=int, default=0)
3739
parser.add_argument("--verbose", "-v", action='store_true')
3840
parser.add_argument("--purepythonparser", "-p", action="store_true")
3941
args = parser.parse_args()
@@ -42,6 +44,7 @@ def perform(ifc_fn, task_id, rule_type, verbose, purepythonparser=False):
4244
ifc_fn=args.file_name,
4345
task_id=args.task_id,
4446
rule_type=args.rule_type,
47+
max_outcomes=args.max_outcomes,
4548
verbose=args.verbose,
4649
purepythonparser=args.purepythonparser
4750
)

backend/apps/ifc_validation/tasks/check_programs.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from apps.ifc_validation_models.settings import TASK_TIMEOUT_LIMIT
1414
from apps.ifc_validation_models.models import ValidationTask
15-
from core.settings import MAX_FILE_SIZE_IN_MB
15+
from core.settings import MAX_FILE_SIZE_IN_MB, MAX_OUTCOMES_PER_RULE
1616

1717
from .logger import logger
1818
from .context import TaskContext
@@ -204,8 +204,9 @@ def check_prerequisites(context:TaskContext):
204204
os.path.join(checks_dir, "check_gherkin.py"),
205205
"--file-name", context.file_path,
206206
"--task-id", str(context.task.id),
207-
"--rule-type", "CRITICAL",
208-
"--purepythonparser"
207+
"--rule-type", "CRITICAL",
208+
"--max-outcomes", str(MAX_OUTCOMES_PER_RULE),
209+
"--purepythonparser",
209210
]
210211
)
211212
raw_output = check_proc_success_or_fail(proc, context.task)
@@ -220,7 +221,8 @@ def check_normative_ia(context:TaskContext):
220221
os.path.join(checks_dir, "check_gherkin.py"),
221222
"--file-name", context.file_path,
222223
"--task-id", str(context.task.id),
223-
"--rule-type", "IMPLEMENTER_AGREEMENT"
224+
"--rule-type", "IMPLEMENTER_AGREEMENT",
225+
"--max-outcomes", str(MAX_OUTCOMES_PER_RULE),
224226
]
225227
)
226228
raw_output = check_proc_success_or_fail(proc, context.task)
@@ -235,7 +237,8 @@ def check_normative_ip(context:TaskContext):
235237
os.path.join(checks_dir, "check_gherkin.py"),
236238
"--file-name", context.file_path,
237239
"--task-id", str(context.task.id),
238-
"--rule-type", "INFORMAL_PROPOSITION"
240+
"--rule-type", "INFORMAL_PROPOSITION",
241+
"--max-outcomes", str(MAX_OUTCOMES_PER_RULE),
239242
]
240243
)
241244
raw_output = check_proc_success_or_fail(proc, context.task)
@@ -250,7 +253,8 @@ def check_industry_practices(context:TaskContext):
250253
os.path.join(checks_dir, "check_gherkin.py"),
251254
"--file-name", context.file_path,
252255
"--task-id", str(context.task.id),
253-
"--rule-type", "INDUSTRY_PRACTICE"
256+
"--rule-type", "INDUSTRY_PRACTICE",
257+
"--max-outcomes", str(MAX_OUTCOMES_PER_RULE),
254258
]
255259
)
256260
raw_output = check_proc_success_or_fail(proc, context.task)
Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,52 @@
1+
import json
2+
import subprocess
3+
import sys
4+
import textwrap
15
import ifcopenshell
26
from .. import TaskContext, logger
37

48
from apps.ifc_validation_models.models import ModelInstance
59

6-
from django.db import transaction
10+
from django.db import transaction
11+
12+
_completion_script_str = textwrap.dedent(
13+
"""
14+
import sys
15+
import json
16+
import ifcopenshell
17+
18+
file_path, step_ids = json.load(sys.stdin)
19+
ifc_file = ifcopenshell.open(file_path)
20+
json.dump([ifc_file[step_id].is_a() for step_id in step_ids], sys.stdout)
21+
"""
22+
)
23+
24+
25+
def _obtain_ifc_types(file_path: str, step_ids: list[int]) -> list[str]:
26+
return json.loads(subprocess.run(
27+
[sys.executable, "-u", "-c", _completion_script_str],
28+
input=json.dumps([file_path, step_ids]),
29+
capture_output=True,
30+
text=True,
31+
check=True,
32+
).stdout)
33+
734

835
def process_instance_completion(context:TaskContext):
936
# the current task doesn't have any execution layer and links instance ids to outcomes
10-
ifc_file = ifcopenshell.open(context.file_path)
37+
model_id = context.request.model.id
38+
model_instances = ModelInstance.objects.filter(model_id=model_id, ifc_type__in=[None, ''])
39+
instance_count = model_instances.count()
40+
logger.info(f'Retrieved {instance_count:,} ModelInstance record(s)')
41+
42+
step_ids = list(
43+
model_instances.values_list("stepfile_id", flat=True)
44+
)
45+
step_id_to_type = dict(zip(step_ids, _obtain_ifc_types(context.file_path, step_ids)))
46+
1147
with transaction.atomic():
12-
model_id = context.request.model.id
13-
model_instances = ModelInstance.objects.filter(model_id=model_id, ifc_type__in=[None, ''])
14-
instance_count = model_instances.count()
15-
logger.info(f'Retrieved {instance_count:,} ModelInstance record(s)')
16-
1748
for inst in model_instances.iterator():
18-
inst.ifc_type = ifc_file[inst.stepfile_id].is_a()
49+
inst.ifc_type = step_id_to_type[inst.stepfile_id]
1950
inst.save()
2051

21-
return f'Updated {instance_count:,} ModelInstance record(s)'
52+
return f'Updated {instance_count:,} ModelInstance record(s)'

0 commit comments

Comments
 (0)