Skip to content

Commit e93bead

Browse files
alexandraBaracderb
andauthored
Celery coverage2 (#976)
* fixed SQL query syntax * cleanup attemps + mlir test failure undo * commented out failing rocmlir test assert * pylint fix * tuning updates * duplicate logger handler * pulled session out of processing function call * utest fix * syntax fix * fixed the timing * added subproc to purge Q by name * pylint * ctrl+c queue drain handle * pylint * stopping active workers on ctrl+x * added enqueue_only arg * merge fix * added cancel_consumer, shutdown_worker cmd line arg + some review fixes * moved cancel consumer to end of tuning * pylint * changing JK file to work with celery, added parallel step for findcompile * fixed JK file syntax * added kill subp by PID to terminate celery workers * checking CI for execute step fail * moved CompileEnqueue job checking stage over from execute * added stage to build DB * running applic to add session * sleep on execute for 30 sec to ensure enqueue * testing with launching celery worker from groovy file * parallel steps inside the same stage * parallel stage edit * added daemonize * running enqueue in background with & * pipe-ing output to file * stdout, stderr from subp * stdout, stderr from subp * reading stoud * added loop exit * removed blocking read * launching celery worker from groovy file * added missing celery_log file * fixed celery cmd * removed detached mode * starting worker before enqueue * removed the background job for enqueue * start/join on subp for celery workers * running enq in the background * removed subp.start * calling subproc.run/join * removed process wait barrier + groovy file update with kill C worker by pid * groovy syntax fix mypy pylint ignore declaring pid var in groovy trying to get pid groovy fix Bump idna from 2.8 to 3.7 (#965) Bumps [idna](https://github.com/kjd/idna) from 2.8 to 3.7. - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst) - [Commits](kjd/idna@v2.8...v3.7) --- updated-dependencies: - dependency-name: idna dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> launching celery for eval per GPU fixed get num_gpu script fix loop index + added --enqueue to find_eval groovy range range fix testing with int cast loop for i in iter testing different loop for loop instead of .each removed for loop var rename removed loops removed printout from go_fish removed for loop added NonCPS directive updated perf_compile and perf_eval with celery runs updated perf_compile and perf_eval with celery runs each replaced elem with it removed all loops * pipeline fix * hardcoding numbers for golden entries * undid perf compile/eval shrink * fix groovy * undid merge of perf runs in perfEval * added enqueue_only cmd line arg * updated update_golden call to write entries with version 1 * commented out solverA test that checks for gfx908 entries (we run a diff arch for perf) * added GPU loop for findEval * fixed groovy echo * fix pid list for celery workers, function for stopping workers in enqueue, enqueue purges queue at start * pass subprocess pointers to tuning setup and join tuning setup to spawned celery workers * kill celery workers when call to worker generation is canceled * extra loggin * added asyncio * fixed counter * resetting job state for in flight jobs with no results * state rest * move purge_queue * trying to update redis key prefix * trying to update redis key prefix * only shutdown celery workers from current session * global_keyprefix * unified prefix nme * updated Q name, global_prefix + result fetch on not new jobs * moved functions into utility files * no-cache * moved enqueue into mituna_interface * moved everything into interfaces * update baseimage in dockerfile * moved prep_tuning and tune in interface * fixins * fixed enum operation * cleanup * fixed Operation check * worker operation fix * fixed operation compare * extra logging * import * removed app.start * removed app.start so we can set configurations * updated Q name in manual worker launch in groovy file * moved machine init in run function * cache machine for celery task to avoid re-init, retrieve worker name in celery task, set gpu_id in celery task * using task_id to differentiate btw different runs and results * cleanup * fixed groovy file celery q names and worker names as per code updates * cache tuna worker objects for celery workers * added subproc for async function * filter eval op for querying gpu_id in celery task * custom error class + cleanup * yapf * README updates * fixed missing args + CTRL+C interrupt catch for async run * fix for worker_launch * updates in groovy to print celery worker output * syntax fix * added logfile printout for compile step * utest updates to accomodate for functions moving around * removed no-cache from docker builds * yapf * removed pid from logname * test * launching workers through tuna * inspecting celery * adding args.fin_steps to redis key prefix to differentiate btw find/perf/eval/compile results in consume * merged parallel branch * removed local prefix * string filter adjustment * added cleaup function for redis results * fixed launch for compile worker * fixed prefix filtering for redis keys * fix prefix issue when no fin_steps present * fixed sess_str to cancel worker * added reply_to for task decorator * prefix fix * string literal fix * updated celery worker name in groovy file * launching worker locally in detach mode * set correct celery env vars to launch worker manually * added CELERY_BROKER env var * setup env vars for rest of utils functions that work with celery * undid groovy utils function name change * explicitly setting TUNA_CELERY_BROKER in docker env * added CELERY_BROKER env var for tuna launch * separated log files for stages * added CELERY_BROKER env var to findEval * moved CELERY_BROKER url to inline * added CELERY_BROKER inline export for each enqueue_call * print proc_id * fix for pid return * escaping & * replace double quotes to eascap $ * fixed stdout/stderr redirect * 123 * 123 * replaced &=046 * reverted single quotes to double * cleanup * cleanup * undid false removal of load_job * sudo for kill -9 * enabling perfCompile/eval stages * fixed log file for perf_eval * fixed celery worker name for perfEval * fixed gpu_id for eval stages * fixed groovy syntax * fixed groovy syntax * checking whoami /etc/pwd * enabling back utests * utest + doc updates * fix for fin_builder utest * syntax fix * fin_eval utest update * moved fin_eval utest step to gpu node and split from coverage * fin_eval utest update * yapf * checking jobs * skipping codecov to test all other CI stages * utest fin_eval fix * added celery_app and celery_tasks to ignore in codecov * yapf * fin_eval utest fic * fineval stage try catch for printing celery logfile * checking prefix * fixed log file in find eval * fixed groovy syntax * removed sudo from kill -9 * try catch for pid kill * try catch block for kill cmd in perfEval * undid update_golden calls in groovy file * checking coverage details * utest for new miopen_lib functions * move miopen_lib utests * utest fix for miopen_lib * fin_builder utest extra coverage for miopen_lib functionality * added test_celery utest * added more to celery utest * fixed import * extra tuna_celery code for utest * pylint * added test_celery to utest call * added test_helper for extra codecov * new test_helper utest * more utests for fin_eval and celery * more fin_eval utests * more celery functions utest added * yapf + test_mituna_interface * yapf + test_mituna_interface * cleanup * fixed utest test_celery check * canceling consumer on early exit for no new jobs * ignoring example/ from coverage * celery launches for pipelines * add env for celery broker * end docker container running enqueue * fix * remote workers will be killed by enqueue, so remove extra kill * kernel clear search performance * update gpu_id tracking * end pipeline enqueue docker with sigkill to allow cleanup * remove docker wait * Revert "remove docker wait" This reverts commit 92930cc. * reset job_counter on sigint * periodic search for new jobs * rebuild enqueue process * reduce logging * test speedup for kernel query * add missing import * test alchemy alternative * test query * cleanup * cleanup + reviews * addressed reviews * utest update post branch pull * fix merge in JK file * fix merge in JK file * merge fix * readded .coveragec file post merge * added check for shutting down celery workers --------- Co-authored-by: Alex Bara <alex.bara@amd.com> Co-authored-by: Christopher Erb <Christopher.Erb@amd.com>
1 parent 9d5d2d9 commit e93bead

16 files changed

Lines changed: 584 additions & 236 deletions

Jenkinsfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,14 @@ pipeline {
9191
}
9292
}
9393
}
94-
/*
9594
stage("Coverage"){
9695
agent { label utils.rocmnode("tunatest") }
9796
steps {
9897
script {
9998
utils.Coverage(branch, branch_master)
10099
}
101100
}
102-
}*/
101+
}
103102
stage("fin find compile"){
104103
agent{ label utils.rocmnode("tunatest") }
105104
steps{

tests/test_celery.py

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
###############################################################################
2+
#
3+
# MIT License
4+
#
5+
# Copyright (c) 2024 Advanced Micro Devices, Inc.
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in all
15+
# copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
# SOFTWARE.
24+
#
25+
###############################################################################
26+
import os
27+
import copy
28+
from time import sleep
29+
from multiprocessing import Value
30+
import aioredis
31+
from sqlalchemy.inspection import inspect
32+
33+
from utils import GoFishArgs, add_test_jobs, add_test_session
34+
from tuna.dbBase.sql_alchemy import DbSession
35+
from tuna.utils.machine_utility import load_machines
36+
from tuna.miopen.db.tables import MIOpenDBTables
37+
from tuna.miopen.miopen_lib import MIOpen
38+
from tuna.miopen.utils.config_type import ConfigType
39+
from tuna.utils.utility import serialize_job_config_row, arch2targetid
40+
from tuna.miopen.celery_tuning.celery_tasks import prep_kwargs
41+
from tuna.machine import Machine
42+
from tuna.libraries import Operation
43+
from tuna.celery_app.celery_workers import launch_worker_per_node
44+
from tuna.celery_app.utility import get_q_name
45+
from tuna.parse_args import TunaArgs, setup_arg_parser
46+
from tuna.miopen.celery_tuning.celery_tasks import prep_worker
47+
from tuna.miopen.worker.fin_utils import compose_config_obj, fin_job
48+
from tuna.miopen.utils.lib_helper import get_worker
49+
50+
51+
def test_celery_workers():
52+
miopen = MIOpen()
53+
miopen.args = GoFishArgs()
54+
miopen.args.label = 'tuna_pytest_celery'
55+
miopen.args.session_id = add_test_session(label=miopen.args.label)
56+
57+
#load jobs
58+
dbt = MIOpenDBTables(config_type=ConfigType.convolution)
59+
num_jobs = add_test_jobs(miopen, miopen.args.session_id, dbt,
60+
miopen.args.label, miopen.args.label,
61+
['miopen_perf_compile'],
62+
'test_add_celery_compile_job',
63+
'miopenConvolutionAlgoGEMM')
64+
#assert num_jobs
65+
num_jobs = 4
66+
67+
machine_lst = load_machines(miopen.args)
68+
machine = machine_lst[0]
69+
miopen.operation = Operation.COMPILE
70+
miopen.dbt = MIOpenDBTables(session_id=miopen.args.session_id,
71+
config_type=ConfigType.convolution)
72+
miopen.args.enqueue_only = False
73+
db_name = os.environ['TUNA_DB_NAME']
74+
75+
#testing get_q_name
76+
q_name = get_q_name(miopen, op_compile=True)
77+
assert q_name == f"compile_q_{db_name}_sess_{miopen.args.session_id}"
78+
q_name = get_q_name(miopen, op_eval=True)
79+
assert q_name == f"eval_q_{db_name}_sess_{miopen.args.session_id}"
80+
81+
#testing prep_tuning
82+
_, subp_list = miopen.prep_tuning()
83+
assert subp_list
84+
for subp in subp_list:
85+
subp.kill()
86+
87+
miopen.args.enqueue_only = True
88+
_, subp_list = miopen.prep_tuning()
89+
assert subp_list == []
90+
91+
92+
cmd = f"celery -A tuna.celery_app.celery_app worker -l info -E -n tuna_HOSTNAME_sess_{miopen.args.session_id} -Q test_{db_name}" #pylint: disable=line-too-long
93+
#testing launch_worker_per_node
94+
subp_list = launch_worker_per_node([machine], cmd, True)
95+
#wait for workers to finish launch
96+
sleep(5)
97+
assert subp_list
98+
assert miopen.cancel_consumer(q_name)
99+
#wait for celery worker shutdown
100+
sleep(5)
101+
102+
for subp in subp_list:
103+
print(subp.pid)
104+
assert subp.poll()
105+
subp.kill()
106+
107+
miopen.args.fin_steps = "miopen_perf_compile"
108+
miopen.db_name = "test_db"
109+
parser = setup_arg_parser(
110+
'Run Performance Tuning on a certain architecture', [
111+
TunaArgs.ARCH, TunaArgs.NUM_CU, TunaArgs.VERSION,
112+
TunaArgs.CONFIG_TYPE, TunaArgs.SESSION_ID, TunaArgs.MACHINES,
113+
TunaArgs.REMOTE_MACHINE, TunaArgs.LABEL, TunaArgs.RESTART_MACHINE,
114+
TunaArgs.DOCKER_NAME, TunaArgs.SHUTDOWN_WORKERS
115+
])
116+
117+
#testing check_fin_args
118+
miopen.check_fin_args(parser)
119+
#testing set_prefix
120+
miopen.set_prefix()
121+
assert (miopen.prefix ==
122+
f"d_test_db_sess_{miopen.args.session_id}_miopen_perf_compile")
123+
124+
#testing update_operation
125+
miopen.update_operation()
126+
assert 'new' in miopen.fetch_state
127+
assert miopen.set_state == 'compile_start'
128+
assert miopen.operation == Operation.COMPILE
129+
130+
#testing has_tunable operation
131+
assert miopen.has_tunable_operation()
132+
133+
with DbSession() as session:
134+
job_query = session.query(
135+
dbt.job_table).filter(dbt.job_table.session == miopen.args.session_id)\
136+
.filter(dbt.job_table.reason=='tuna_pytest_celery')
137+
job_query.update({dbt.job_table.state: 'compile_start'})
138+
session.commit()
139+
#testing reset_job_staet_on_ctrl_c
140+
miopen.reset_job_state_on_ctrl_c()
141+
count = session.query(dbt.job_table).filter(dbt.job_table.session==miopen.args.session_id)\
142+
.filter(dbt.job_table.state=='new').count()
143+
#assert count == num_jobs
144+
145+
with DbSession() as session:
146+
jobs = miopen.get_jobs(session, miopen.fetch_state, miopen.set_state,
147+
miopen.args.session_id)
148+
assert jobs
149+
#testing get_context_list
150+
context_list = miopen.get_context_list(session, [job for job in jobs])
151+
assert context_list
152+
assert len(context_list) == 4
153+
entries = [job for job in jobs]
154+
155+
job_config_rows = miopen.compose_work_objs_fin(session, entries, miopen.dbt)
156+
assert job_config_rows
157+
158+
job_dct, config_dct = serialize_job_config_row(job_config_rows[0])
159+
#testing arch2targetid
160+
arch = arch2targetid(miopen.dbt.session.arch)
161+
assert arch == "gfx90a:sram-ecc+:xnack-"
162+
steps = ['alloc_buf', 'fill_buf', miopen.args.fin_steps[0]]
163+
164+
#testing fin_job
165+
fjob = fin_job(steps, True, job_config_rows[0][0], job_config_rows[0][1],
166+
miopen.dbt)
167+
assert fjob
168+
f_vals = miopen.get_f_vals(machine, range(0))
169+
kwargs = miopen.get_kwargs(0, f_vals, tuning=True)
170+
kwargs['job'] = job_dct
171+
kwargs['config'] = config_dct
172+
kwargs['avail_gpus'] = 1
173+
fdb_attr = [column.name for column in inspect(miopen.dbt.find_db_table).c]
174+
fdb_attr.remove("insert_ts")
175+
fdb_attr.remove("update_ts")
176+
context = {
177+
'job': job_dct,
178+
'config': config_dct,
179+
'operation': Operation.EVAL,
180+
'arch': miopen.dbt.session.arch,
181+
'num_cu': miopen.dbt.session.num_cu,
182+
'kwargs': kwargs,
183+
'fdb_attr': fdb_attr
184+
}
185+
186+
worker = prep_worker(copy.deepcopy(context))
187+
worker_kwargs = prep_kwargs(
188+
context['kwargs'],
189+
[context['job'], context['config'], context['operation']])
190+
assert worker_kwargs['config']
191+
assert worker_kwargs['job']
192+
assert worker_kwargs['fin_steps'] == ['miopen_perf_compile']
193+
miopen.operation = Operation.EVAL
194+
fin_eval = get_worker(worker_kwargs, miopen.operation)
195+
196+
#testing fin_job
197+
fjob = fin_job(steps, True, job_config_rows[0][0], job_config_rows[0][1],
198+
miopen.dbt)
199+
#testing fin_pdb_input
200+
f_job = fin_eval.fin_pdb_input(fjob)
201+
assert f_job[0]['solvers'] == ['GemmBwd1x1_stride2']
202+
assert f_job[0]['miopen_perf_compile_result'] == [{
203+
'solver_name': 'GemmBwd1x1_stride2',
204+
'perf_compiled': False,
205+
'kernel_objects': []
206+
}]
207+
208+
#testing fin_fdb_input
209+
steps = ['alloc_buf', 'fill_buf', ['miopen_find_compile']]
210+
f_job = fin_eval.fin_fdb_input(fjob)
211+
assert f_job
212+
assert f_job[0]['miopen_find_compile_result'] == [{
213+
'solver_name': 'GemmBwd1x1_stride2',
214+
'find_compiled': False,
215+
'kernel_objects': []
216+
}]
217+
218+
#testing compose_config_obj
219+
conf_obj = compose_config_obj(job_config_rows[0][1], ConfigType.convolution)
220+
assert conf_obj
221+
assert conf_obj[
222+
'driver'] == "./bin/MIOpenDriver conv --batchsize 128 --spatial_dim 2 --pad_h 0 --pad_w 0 --pad_d 0 --conv_stride_h 2 --conv_stride_w 2 --conv_stride_d 0 --dilation_h 1 --dilation_w 1 --dilation_d 0 --group_count 1 --mode conv --pad_mode default --trans_output_pad_h 0 --trans_output_pad_w 0 --trans_output_pad_d 0 --out_layout NCHW --in_layout NCHW --fil_layout NCHW --in_d 1 --in_h 14 --in_w 14 --fil_d 1 --fil_h 1 --fil_w 1 --in_channels 1024 --out_channels 2048 --forw 2"
223+
224+
miopen.operation = Operation.COMPILE
225+
f_vals = miopen.get_f_vals(Machine(local_machine=True), range(0))
226+
kwargs = miopen.get_kwargs(0, f_vals, tuning=True)
227+
fdb_attr = [column.name for column in inspect(miopen.dbt.find_db_table).c]
228+
fdb_attr.remove("insert_ts")
229+
fdb_attr.remove("update_ts")
230+
231+
redis = aioredis.from_url("redis://localhost:6379/15")
232+
print('Established redis connection')
233+
counter = 1
234+
235+
res_set = []
236+
for elem in job_config_rows:
237+
job_dict, config_dict = serialize_job_config_row(elem)
238+
context = {
239+
'job': job_dict,
240+
'config': config_dict,
241+
'operation': miopen.operation,
242+
'arch': miopen.dbt.session.arch,
243+
'num_cu': miopen.dbt.session.num_cu,
244+
'kwargs': kwargs,
245+
'fdb_attr': fdb_attr
246+
}
247+
248+
worker = prep_worker(copy.deepcopy(context))
249+
worker.dbt = miopen.dbt
250+
worker.fin_steps = miopen.args.fin_steps
251+
fin_json = worker.run()
252+
res_set.append((fin_json, context))
253+
assert redis.set(f"celery-task-meta-{counter}", fin_json)
254+
counter += 1
255+
256+
print('Consuming from redis')
257+
assert miopen.consume(job_counter=counter, prefix=None)
258+
redis.close()
259+
260+
with DbSession() as session:
261+
for fin_json, context in res_set:
262+
#testing process_fin_builder_results
263+
miopen.process_fin_builder_results(session, fin_json, context)
264+
count = session.query(dbt.job_table).filter(
265+
dbt.job_table.session == miopen.args.session_id).count()
266+
assert count == num_jobs
267+
268+
with DbSession() as session:
269+
job_query = session.query(
270+
dbt.job_table).filter(dbt.job_table.session == miopen.args.session_id)\
271+
.filter(dbt.job_table.reason=='tuna_pytest_celery')
272+
job_query.update({dbt.job_table.state: 'new'})
273+
session.commit()
274+
275+
db_name = os.environ['TUNA_DB_NAME']
276+
#testing enqueue_jobs
277+
job_counter = Value('i', 4)
278+
miopen.enqueue_jobs(job_counter, 1, f"test_{db_name}")
279+
print('Done enqueue')
280+
with DbSession() as session:
281+
count = session.query(dbt.job_table).filter(dbt.job_table.session==miopen.args.session_id)\
282+
.filter(dbt.job_table.state=='compile_start').count()
283+
assert count == 4

tests/test_dbBase.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ def connect_db():
4848
db_name = ENV_VARS['db_name']
4949
try:
5050
ENGINE.execute('Use {}'.format(db_name))
51-
return
5251
except OperationalError: # as err:
5352
LOGGER.warning('Database %s does not exist, attempting to create database',
5453
db_name)

0 commit comments

Comments
 (0)