From 00ebba39f7e81d2b52bfb3be458f9825e6d7c070 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 14 Mar 2025 00:53:08 +0800 Subject: add jobgraph stub --- tests/modules/async/jobgraph.lua | 7 +++++++ tests/modules/async/runjobs.lua | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 tests/modules/async/jobgraph.lua create mode 100644 tests/modules/async/runjobs.lua (limited to 'tests/modules/async') diff --git a/tests/modules/async/jobgraph.lua b/tests/modules/async/jobgraph.lua new file mode 100644 index 000000000..dd8cb05f8 --- /dev/null +++ b/tests/modules/async/jobgraph.lua @@ -0,0 +1,7 @@ +import("core.base.scheduler") +import("async.jobgraph") + +function main() + +end + diff --git a/tests/modules/async/runjobs.lua b/tests/modules/async/runjobs.lua new file mode 100644 index 000000000..4e2a98cc0 --- /dev/null +++ b/tests/modules/async/runjobs.lua @@ -0,0 +1,43 @@ +import("core.base.scheduler") +import("private.async.jobpool") +import("async.runjobs") + +function _jobfunc(index, total, opt) + print("%s: run job (%d/%d)", scheduler.co_running(), index, total) + local dt = os.mclock() + os.sleep(1000) + dt = os.mclock() - dt + print("%s: run job (%d/%d) end, progress: %s, dt: %d ms", scheduler.co_running(), index, total, opt.progress, dt) +end + +function main() + + -- test callback + print("==================================== test callback ====================================") + local t = os.mclock() + runjobs("test", _jobfunc, {total = 100, comax = 6, timeout = 1000, timer = function (running_jobs_indices) + print("%s: timeout (%d ms), running: %s", scheduler.co_running(), os.mclock() - t, table.concat(running_jobs_indices, ",")) + end}) + + -- test jobs + print("==================================== test jobs ====================================") + local jobs = jobpool.new() + local root = jobs:addjob("job/root", function (index, total, opt) + _jobfunc(index, total, opt) + end) + for i = 1, 3 do + local job = jobs:addjob("job/" .. i, function (index, total, opt) + _jobfunc(index, total, opt) + end, {rootjob = root}) + for j = 1, 50 do + jobs:addjob("job/" .. i .. "/" .. j, function (index, total, opt) + _jobfunc(index, total, opt) + end, {rootjob = job}) + end + end + t = os.mclock() + runjobs("test", jobs, {comax = 6, timeout = 1000, timer = function (running_jobs_indices) + print("%s: timeout (%d ms), running: %s", scheduler.co_running(), os.mclock() - t, table.concat(running_jobs_indices, ",")) + end}) +end + -- cgit v1.3.1 From 1621db050a13474f4d79d02c4d306013770d35b4 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 18 Mar 2025 23:55:15 +0800 Subject: add jobgraph.new --- tests/modules/async/jobgraph.lua | 4 ++-- xmake/modules/async/jobgraph.lua | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'tests/modules/async') diff --git a/tests/modules/async/jobgraph.lua b/tests/modules/async/jobgraph.lua index dd8cb05f8..7a0b87c65 100644 --- a/tests/modules/async/jobgraph.lua +++ b/tests/modules/async/jobgraph.lua @@ -1,7 +1,7 @@ -import("core.base.scheduler") import("async.jobgraph") function main() - + local gh = jobgraph.new() + print(gh) end diff --git a/xmake/modules/async/jobgraph.lua b/xmake/modules/async/jobgraph.lua index 519544cf2..3fd36194a 100644 --- a/xmake/modules/async/jobgraph.lua +++ b/xmake/modules/async/jobgraph.lua @@ -20,17 +20,23 @@ -- imports import("core.base.object") +import("core.base.list") import("core.base.graph") -- define module -local jobgraph = jobgraph or object {_init = {"_size"}} +local jobgraph = jobgraph or object {_init = {"_jobs", "_graph"}} + +-- get jobs +function jobgraph:jobs() + return self._jobs +end -- tostring function jobgraph:__tostring() - return "" + return string.format("", self:jobs():size()) end -- new a jobgraph function new() - return jobgraph {0} + return jobgraph {list.new(), graph.new(true)} end -- cgit v1.3.1 From 6785ce5822f298ce64684548dfc9d35ec8dd5030 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 19 Mar 2025 23:03:25 +0800 Subject: improve runjobs tests --- tests/modules/async/jobgraph.lua | 7 ------ tests/modules/async/run_callback.lua | 19 ++++++++++++++++ tests/modules/async/run_jobgraph.lua | 28 +++++++++++++++++++++++ tests/modules/async/run_jobpool.lua | 28 +++++++++++++++++++++++ tests/modules/async/runjobs.lua | 43 ------------------------------------ xmake/modules/async/jobgraph.lua | 15 +++++++++++++ 6 files changed, 90 insertions(+), 50 deletions(-) delete mode 100644 tests/modules/async/jobgraph.lua create mode 100644 tests/modules/async/run_callback.lua create mode 100644 tests/modules/async/run_jobgraph.lua create mode 100644 tests/modules/async/run_jobpool.lua delete mode 100644 tests/modules/async/runjobs.lua (limited to 'tests/modules/async') diff --git a/tests/modules/async/jobgraph.lua b/tests/modules/async/jobgraph.lua deleted file mode 100644 index 7a0b87c65..000000000 --- a/tests/modules/async/jobgraph.lua +++ /dev/null @@ -1,7 +0,0 @@ -import("async.jobgraph") - -function main() - local gh = jobgraph.new() - print(gh) -end - diff --git a/tests/modules/async/run_callback.lua b/tests/modules/async/run_callback.lua new file mode 100644 index 000000000..21e75014b --- /dev/null +++ b/tests/modules/async/run_callback.lua @@ -0,0 +1,19 @@ +import("core.base.scheduler") +import("async.runjobs") + +function _jobfunc(index, total, opt) + print("%s: run job (%d/%d)", scheduler.co_running(), index, total) + local dt = os.mclock() + os.sleep(1000) + dt = os.mclock() - dt + print("%s: run job (%d/%d) end, progress: %s, dt: %d ms", scheduler.co_running(), index, total, opt.progress, dt) +end + +function main() + print("==================================== test callback ====================================") + local t = os.mclock() + runjobs("test", _jobfunc, {total = 100, comax = 6, timeout = 1000, timer = function (running_jobs_indices) + print("%s: timeout (%d ms), running: %s", scheduler.co_running(), os.mclock() - t, table.concat(running_jobs_indices, ",")) + end}) +end + diff --git a/tests/modules/async/run_jobgraph.lua b/tests/modules/async/run_jobgraph.lua new file mode 100644 index 000000000..bcf5be2fd --- /dev/null +++ b/tests/modules/async/run_jobgraph.lua @@ -0,0 +1,28 @@ +import("core.base.scheduler") +import("async.jobgraph") +import("async.runjobs") + +function _jobfunc(job, opt) + print("%s: run job (%s)", scheduler.co_running(), job.name) + local dt = os.mclock() + os.sleep(1000) + dt = os.mclock() - dt + print("%s: run job (%s) end, progress: %s, dt: %d ms", scheduler.co_running(), job.name, opt.progress, dt) +end + +function main() + print("==================================== test jobpool ====================================") + local jobs = jobgraph.new() + jobs:add_job("job/root", _jobfunc) + for i = 1, 3 do + jobs:add_job("job/" .. i, _jobfunc) + for j = 1, 50 do + jobs:add_job("job/" .. i .. "/" .. j, _jobfunc) + end + end + t = os.mclock() + runjobs("test", jobs, {comax = 6, timeout = 1000, timer = function (running_jobs_indices) + print("%s: timeout (%d ms), running: %s", scheduler.co_running(), os.mclock() - t, table.concat(running_jobs_indices, ",")) + end}) +end + diff --git a/tests/modules/async/run_jobpool.lua b/tests/modules/async/run_jobpool.lua new file mode 100644 index 000000000..5de54e36c --- /dev/null +++ b/tests/modules/async/run_jobpool.lua @@ -0,0 +1,28 @@ +import("core.base.scheduler") +import("private.async.jobpool") +import("async.runjobs") + +function _jobfunc(index, total, opt) + print("%s: run job (%d/%d)", scheduler.co_running(), index, total) + local dt = os.mclock() + os.sleep(1000) + dt = os.mclock() - dt + print("%s: run job (%d/%d) end, progress: %s, dt: %d ms", scheduler.co_running(), index, total, opt.progress, dt) +end + +function main() + print("==================================== test jobpool ====================================") + local jobs = jobpool.new() + local root = jobs:addjob("job/root", _jobfunc) + for i = 1, 3 do + local job = jobs:addjob("job/" .. i, _jobfunc, {rootjob = root}) + for j = 1, 50 do + jobs:addjob("job/" .. i .. "/" .. j, _jobfunc, {rootjob = job}) + end + end + t = os.mclock() + runjobs("test", jobs, {comax = 6, timeout = 1000, timer = function (running_jobs_indices) + print("%s: timeout (%d ms), running: %s", scheduler.co_running(), os.mclock() - t, table.concat(running_jobs_indices, ",")) + end}) +end + diff --git a/tests/modules/async/runjobs.lua b/tests/modules/async/runjobs.lua deleted file mode 100644 index 4e2a98cc0..000000000 --- a/tests/modules/async/runjobs.lua +++ /dev/null @@ -1,43 +0,0 @@ -import("core.base.scheduler") -import("private.async.jobpool") -import("async.runjobs") - -function _jobfunc(index, total, opt) - print("%s: run job (%d/%d)", scheduler.co_running(), index, total) - local dt = os.mclock() - os.sleep(1000) - dt = os.mclock() - dt - print("%s: run job (%d/%d) end, progress: %s, dt: %d ms", scheduler.co_running(), index, total, opt.progress, dt) -end - -function main() - - -- test callback - print("==================================== test callback ====================================") - local t = os.mclock() - runjobs("test", _jobfunc, {total = 100, comax = 6, timeout = 1000, timer = function (running_jobs_indices) - print("%s: timeout (%d ms), running: %s", scheduler.co_running(), os.mclock() - t, table.concat(running_jobs_indices, ",")) - end}) - - -- test jobs - print("==================================== test jobs ====================================") - local jobs = jobpool.new() - local root = jobs:addjob("job/root", function (index, total, opt) - _jobfunc(index, total, opt) - end) - for i = 1, 3 do - local job = jobs:addjob("job/" .. i, function (index, total, opt) - _jobfunc(index, total, opt) - end, {rootjob = root}) - for j = 1, 50 do - jobs:addjob("job/" .. i .. "/" .. j, function (index, total, opt) - _jobfunc(index, total, opt) - end, {rootjob = job}) - end - end - t = os.mclock() - runjobs("test", jobs, {comax = 6, timeout = 1000, timer = function (running_jobs_indices) - print("%s: timeout (%d ms), running: %s", scheduler.co_running(), os.mclock() - t, table.concat(running_jobs_indices, ",")) - end}) -end - diff --git a/xmake/modules/async/jobgraph.lua b/xmake/modules/async/jobgraph.lua index 3fd36194a..30513ae56 100644 --- a/xmake/modules/async/jobgraph.lua +++ b/xmake/modules/async/jobgraph.lua @@ -31,6 +31,21 @@ function jobgraph:jobs() return self._jobs end +-- add a job to the jobgraph +-- +-- e.g. +-- jobgraph:add_job("xxx", function (job, opt) +-- end) +-- +-- @param name the job name +-- @param run the job run command/script +-- @param opt the job options +-- +function jobgraph:add_job(name, run, opt) + local job = {name = name, run = run, opt = opt} + self:jobs():insert(job) +end + -- tostring function jobgraph:__tostring() return string.format("", self:jobs():size()) -- cgit v1.3.1 From f8346ab6e40bdcf9506f1400f74860bbcea764ff Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 19 Mar 2025 23:23:55 +0800 Subject: improve jobgraph tests --- tests/modules/async/run_jobgraph.lua | 13 ++++++----- xmake/modules/async/jobgraph.lua | 44 ++++++++++++++++++++++++++++++++---- xmake/modules/async/runjobs.lua | 5 ++++ 3 files changed, 51 insertions(+), 11 deletions(-) (limited to 'tests/modules/async') diff --git a/tests/modules/async/run_jobgraph.lua b/tests/modules/async/run_jobgraph.lua index bcf5be2fd..ec9c9175f 100644 --- a/tests/modules/async/run_jobgraph.lua +++ b/tests/modules/async/run_jobgraph.lua @@ -2,22 +2,23 @@ import("core.base.scheduler") import("async.jobgraph") import("async.runjobs") -function _jobfunc(job, opt) - print("%s: run job (%s)", scheduler.co_running(), job.name) +function _jobfunc(index, total, opt) + print("%s: run job (%d/%d)", scheduler.co_running(), index, total) local dt = os.mclock() os.sleep(1000) dt = os.mclock() - dt - print("%s: run job (%s) end, progress: %s, dt: %d ms", scheduler.co_running(), job.name, opt.progress, dt) + print("%s: run job (%d/%d) end, progress: %s, dt: %d ms", scheduler.co_running(), index, total, opt.progress, dt) end function main() print("==================================== test jobpool ====================================") local jobs = jobgraph.new() - jobs:add_job("job/root", _jobfunc) + jobs:add("job/root", _jobfunc) for i = 1, 3 do - jobs:add_job("job/" .. i, _jobfunc) + jobs:add("job/" .. i, _jobfunc) for j = 1, 50 do - jobs:add_job("job/" .. i .. "/" .. j, _jobfunc) + jobs:add("job/" .. i .. "/" .. j, _jobfunc) + jobs:add_deps("job/" .. i .. "/" .. j, "job/" .. i, "job/root") end end t = os.mclock() diff --git a/xmake/modules/async/jobgraph.lua b/xmake/modules/async/jobgraph.lua index 30513ae56..313bc2d11 100644 --- a/xmake/modules/async/jobgraph.lua +++ b/xmake/modules/async/jobgraph.lua @@ -24,7 +24,16 @@ import("core.base.list") import("core.base.graph") -- define module -local jobgraph = jobgraph or object {_init = {"_jobs", "_graph"}} +local jobqueue = jobqueue or object {_init = {"_jobgraph"}} +local jobgraph = jobgraph or object {_init = {"_jobs", "_graph", "_dirty"}} + +-- remove the given job from the job queue +function jobqueue:remove(job) +end + +-- get a free job from the job queue +function jobqueue:getfree() +end -- get jobs function jobgraph:jobs() @@ -34,24 +43,49 @@ end -- add a job to the jobgraph -- -- e.g. --- jobgraph:add_job("xxx", function (job, opt) +-- jobgraph:add("xxx", function (index, total, opt) -- end) -- -- @param name the job name -- @param run the job run command/script -- @param opt the job options -- -function jobgraph:add_job(name, run, opt) +function jobgraph:add(name, run, opt) local job = {name = name, run = run, opt = opt} self:jobs():insert(job) + self._dirty = true +end + +-- remove a given job +function jobgraph:remove(name) + self._dirty = true +end + +-- add job deps, e.g. add_deps(a, b, c, ...): a -> b -> c, ... +function jobgraph:add_deps(...) + local deps = table.pack(...) +end + +-- add jog group +function jobgraph:add_group(name, callback) +end + +-- build a job queue +function jobgraph:build() + return jobqueue {self} +end + +-- get job size +function jobgraph:size() + return self:jobs():size() end -- tostring function jobgraph:__tostring() - return string.format("", self:jobs():size()) + return string.format("", self:size()) end -- new a jobgraph function new() - return jobgraph {list.new(), graph.new(true)} + return jobgraph {list.new(), graph.new(true), false} end diff --git a/xmake/modules/async/runjobs.lua b/xmake/modules/async/runjobs.lua index 0c2a6f366..959eb1e77 100644 --- a/xmake/modules/async/runjobs.lua +++ b/xmake/modules/async/runjobs.lua @@ -64,6 +64,11 @@ function main(name, jobs, opt) local group_name = name local jobs_cb = type(jobs) == "function" and jobs or nil assert(timeout < 60000, "runjobs: invalid timeout!") + + -- build jobs queue + if jobs.build then + jobs = jobs:build() + end assert(jobs, "runjobs: no jobs!") -- show waiting tips? -- cgit v1.3.1 From bc4f14679956d6eac336cb23d72e5e91c189a5bf Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 19 Mar 2025 23:35:27 +0800 Subject: add deps for jobgraph --- tests/modules/async/run_jobgraph.lua | 2 +- xmake/modules/async/jobgraph.lua | 31 ++++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) (limited to 'tests/modules/async') diff --git a/tests/modules/async/run_jobgraph.lua b/tests/modules/async/run_jobgraph.lua index ec9c9175f..a3e1edeb3 100644 --- a/tests/modules/async/run_jobgraph.lua +++ b/tests/modules/async/run_jobgraph.lua @@ -11,7 +11,7 @@ function _jobfunc(index, total, opt) end function main() - print("==================================== test jobpool ====================================") + print("==================================== test jobgraph ====================================") local jobs = jobgraph.new() jobs:add("job/root", _jobfunc) for i = 1, 3 do diff --git a/xmake/modules/async/jobgraph.lua b/xmake/modules/async/jobgraph.lua index 612e56dee..684b7d7d8 100644 --- a/xmake/modules/async/jobgraph.lua +++ b/xmake/modules/async/jobgraph.lua @@ -25,7 +25,7 @@ import("core.base.graph") -- define module local jobqueue = jobqueue or object {_init = {"_jobgraph"}} -local jobgraph = jobgraph or object {_init = {"_jobs", "_size", "_deps", "_dirty"}} +local jobgraph = jobgraph or object {_init = {"_name", "_jobs", "_size", "_deps", "_dirty"}} -- build the job queue function jobqueue:_build() @@ -87,9 +87,21 @@ end -- add job deps, e.g. add_deps(a, b, c, ...): a -> b -> c, ... function jobgraph:add_deps(...) - -- TODO - local deps = table.pack(...) - self._dirty = true + local prev + local dirty + local jobs = self._jobs + local deps = self._deps + for _, name in ipairs(table.pack(...)) do + local curr = assert(jobs[name], "job(%s) not found in jobgraph(%s)", name, self) + if prev then + deps:add_edge(prev, curr) + dirty = true + end + prev = curr + end + if dirty then + self._dirty = true + end end -- add jog group @@ -108,6 +120,11 @@ function jobgraph:jobs() return self._jobs end +-- get jobgraph name +function jobgraph:name() + return self._name +end + -- get job size function jobgraph:size() return self._size @@ -115,10 +132,10 @@ end -- tostring function jobgraph:__tostring() - return string.format("", self:size()) + return string.format("", self:name() or "anonymous", self:size()) end -- new a jobgraph -function new() - return jobgraph {{}, 0, graph.new(true), false} +function new(name) + return jobgraph {name, {}, 0, graph.new(true), false} end -- cgit v1.3.1 From d31fc3eb8ade62b0d80280f22329bb132ea95cfc Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 22 Mar 2025 22:28:30 +0800 Subject: support for job group --- tests/modules/async/run_jobgraph.lua | 26 ++++++++++++-- xmake/modules/async/jobgraph.lua | 68 +++++++++++++++++++++++++++++------- 2 files changed, 79 insertions(+), 15 deletions(-) (limited to 'tests/modules/async') diff --git a/tests/modules/async/run_jobgraph.lua b/tests/modules/async/run_jobgraph.lua index a3e1edeb3..bc1b5500f 100644 --- a/tests/modules/async/run_jobgraph.lua +++ b/tests/modules/async/run_jobgraph.lua @@ -10,8 +10,8 @@ function _jobfunc(index, total, opt) print("%s: run job (%d/%d) end, progress: %s, dt: %d ms", scheduler.co_running(), index, total, opt.progress, dt) end -function main() - print("==================================== test jobgraph ====================================") +function _test_basic() + print("==================================== test basic ====================================") local jobs = jobgraph.new() jobs:add("job/root", _jobfunc) for i = 1, 3 do @@ -27,3 +27,25 @@ function main() end}) end +function _test_group() + print("==================================== test group ====================================") + local jobs = jobgraph.new() + jobs:add("job/root", _jobfunc) + for i = 1, 3 do + jobs:add("job/" .. i, _jobfunc, {groups = "bar"}) + for j = 1, 50 do + jobs:add("job/" .. i .. "/" .. j, _jobfunc, {groups = "foo"}) + end + end + jobs:add_deps("foo", "bar", "job/root") + t = os.mclock() + runjobs("test", jobs, {comax = 6, timeout = 1000, timer = function (running_jobs_indices) + print("%s: timeout (%d ms), running: %s", scheduler.co_running(), os.mclock() - t, table.concat(running_jobs_indices, ",")) + end}) +end + +function main() + _test_basic() + _test_group() +end + diff --git a/xmake/modules/async/jobgraph.lua b/xmake/modules/async/jobgraph.lua index ee3a6f274..edf3cfe81 100644 --- a/xmake/modules/async/jobgraph.lua +++ b/xmake/modules/async/jobgraph.lua @@ -37,6 +37,7 @@ end -- get a free job from the job queue function jobqueue:getfree() local dag = self._dag +::continue:: local freejob, has_cycle = dag:partial_topo_sort_next() if has_cycle then local names = {} @@ -49,6 +50,11 @@ function jobqueue:getfree() end raise("%s: circular job dependency detected!\n%s", self._jobgraph, table.concat(names, "\n -> ")) end + -- if it's a fake job, we need to skip it and continue to get the next job + if freejob and not freejob.run then + dag:partial_topo_sort_remove(freejob) + goto continue + end return freejob end @@ -60,23 +66,25 @@ end -- -- @param name the job name -- @param run the job run command/script --- @param opt the job options, e.g. {group = "xxx"} +-- @param opt the job options, e.g. {groups = {"xxx"}} -- function jobgraph:add(name, run, opt) + opt = opt or {} local jobs = self._jobs if not jobs[name] then local job = {name = name, run = run, opt = opt} jobs[name] = job self._size = self._size + 1 - local group_name = opt.group - if group_name then - local groups = self._groups[group_name] - if not groups then - groups = {} - self._groups[group_name] = groups + if opt.groups then + for _, group_name in ipairs(opt.groups) do + local groups = self._groups[group_name] + if not groups then + groups = {} + self._groups[group_name] = groups + end + table.insert(groups, job) end - table.insert(groups, job) end end end @@ -97,19 +105,53 @@ end -- add job deps, e.g. add_deps(a, b, c, ...): a -> b -> c, ... function jobgraph:add_deps(...) local prev + local prev_is_group local dag = self._dag local jobs = self._jobs + local groups = self._groups for _, name in ipairs(table.pack(...)) do - local curr = assert(jobs[name], "job(%s) not found in jobgraph(%s)", name, self) + local curr_is_group = false + local curr = jobs[name] + if not curr then + curr = groups[name] + curr_is_group = true + end + assert(curr, "job(%s) not found in jobgraph(%s)", name, self) if prev then - if not dag:has_edge(prev, curr) then - dag:add_edge(prev, curr) + if prev_is_group and curr_is_group then + -- we use a fake task as a node to bridge the two groups. + local fakejob = {} + for _, job in ipairs(prev) do + if not dag:has_edge(job, fakejob) then + dag:add_edge(job, fakejob) + end + end + for _, job in ipairs(curr) do + if not dag:has_edge(fakejob, job) then + dag:add_edge(fakejob, job) + end + end + elseif curr_is_group then + for _, job in ipairs(curr) do + if not dag:has_edge(prev, job) then + dag:add_edge(prev, job) + end + end + elseif prev_is_group then + for _, job in ipairs(prev) do + if not dag:has_edge(job, curr) then + dag:add_edge(job, curr) + end + end + else + if not dag:has_edge(prev, curr) then + dag:add_edge(prev, curr) + end end end prev = curr + prev_is_group = curr_is_group end - -- TODO - -- add groups jobs end -- build a job queue -- cgit v1.3.1 From 8beb0732ff716cd5b3d7a40744b1d239302fdb4b Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 27 Mar 2025 22:49:41 +0800 Subject: rename add_deps to add_orders --- tests/modules/async/run_jobgraph.lua | 4 ++-- xmake/actions/build/target_utils.lua | 15 +++++++++------ xmake/core/base/graph.lua | 18 +++++++++++------- xmake/modules/async/jobgraph.lua | 20 ++++++++++---------- 4 files changed, 32 insertions(+), 25 deletions(-) (limited to 'tests/modules/async') diff --git a/tests/modules/async/run_jobgraph.lua b/tests/modules/async/run_jobgraph.lua index bc1b5500f..9b8f529ed 100644 --- a/tests/modules/async/run_jobgraph.lua +++ b/tests/modules/async/run_jobgraph.lua @@ -18,7 +18,7 @@ function _test_basic() jobs:add("job/" .. i, _jobfunc) for j = 1, 50 do jobs:add("job/" .. i .. "/" .. j, _jobfunc) - jobs:add_deps("job/" .. i .. "/" .. j, "job/" .. i, "job/root") + jobs:add_orders("job/" .. i .. "/" .. j, "job/" .. i, "job/root") end end t = os.mclock() @@ -37,7 +37,7 @@ function _test_group() jobs:add("job/" .. i .. "/" .. j, _jobfunc, {groups = "foo"}) end end - jobs:add_deps("foo", "bar", "job/root") + jobs:add_orders("foo", "bar", "job/root") t = os.mclock() runjobs("test", jobs, {comax = 6, timeout = 1000, timer = function (running_jobs_indices) print("%s: timeout (%d ms), running: %s", scheduler.co_running(), os.mclock() - t, table.concat(running_jobs_indices, ",")) diff --git a/xmake/actions/build/target_utils.lua b/xmake/actions/build/target_utils.lua index 1fef599ac..b91b436f0 100644 --- a/xmake/actions/build/target_utils.lua +++ b/xmake/actions/build/target_utils.lua @@ -50,7 +50,7 @@ function _add_stage_jobs_for_target(jobgraph, target, stage, opt) end -- call target and rules script - local jobdeps = {} + local joborders = {} for _, instance in ipairs(instances) do local script = instance:script(script_name) if script then @@ -59,7 +59,7 @@ function _add_stage_jobs_for_target(jobgraph, target, stage, opt) -- TODO bind target envs script(target, {progress = progress}) end, {groups = group_name}) - table.insert(jobdeps, jobname) + table.insert(joborders, jobname) else local scriptcmd = instance:script(scriptcmd_name) if scriptcmd then @@ -70,13 +70,16 @@ function _add_stage_jobs_for_target(jobgraph, target, stage, opt) scriptcmd(target, batchcmds_, {progress = progress}) batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) end, {groups = group_name}) - table.insert(jobdeps, jobname) + table.insert(joborders, jobname) end end end - -- add job deps - jobgraph:add_deps(jobdeps) + -- add job orders + if #joborders > 0 then + jobgraph:add_orders(joborders) + return group_name + end end -- add jobs for the given target @@ -90,7 +93,7 @@ function _add_jobs_for_target(jobgraph, target, opt) local group = _add_stage_jobs_for_target(jobgraph, target, "", opt) local group_before = _add_stage_jobs_for_target(jobgraph, target, "before", opt) local group_after = _add_stage_jobs_for_target(jobgraph, target, "after", opt) - jobgraph:add_deps(group_after, group, group_before) + jobgraph:add_orders(group_before, group, group_after) end -- add jobs for the given target and deps diff --git a/xmake/core/base/graph.lua b/xmake/core/base/graph.lua index 43b43ce3c..db8682b21 100644 --- a/xmake/core/base/graph.lua +++ b/xmake/core/base/graph.lua @@ -173,12 +173,14 @@ end -- -- e.g. -- --- add_edge(a, b) -- a depend on b --- add_edge(b, c) -- b depend on c +-- edges: a (indegree: 0) -> b -> c -- --- local node1, has_cycle = g:partial_topo_sort_next() -- return c +-- add_edge(a, b) +-- add_edge(b, c) +-- +-- local node1, has_cycle = g:partial_topo_sort_next() -- return a -- local node2, has_cycle = g:partial_topo_sort_next() -- return b --- local node3, has_cycle = g:partial_topo_sort_next() -- return a +-- local node3, has_cycle = g:partial_topo_sort_next() -- return c -- local node4, has_cycle = g:partial_topo_sort_next() -- return nil (empty, all done) -- function graph:partial_topo_sort_next() @@ -250,10 +252,12 @@ end -- -- e.g. -- --- add_edge(a, b) -- a depend on b --- add_edge(b, c) -- b depend on c +-- edges: a (indegree: 0) -> b -> c +-- +-- add_edge(a, b) +-- add_edge(b, c) -- --- it will return {c, b, a} +-- it will return {a, b, c} function graph:topo_sort() if not self:is_directed() then return diff --git a/xmake/modules/async/jobgraph.lua b/xmake/modules/async/jobgraph.lua index b72fb5b16..fe42f6647 100644 --- a/xmake/modules/async/jobgraph.lua +++ b/xmake/modules/async/jobgraph.lua @@ -104,25 +104,25 @@ function jobgraph:remove(name) end end --- add job deps, e.g. add_deps(a, b, c, ...): a -> b -> c, ... +-- add job orders, e.g. add_orders(a, b, c, ...): a -> b -> c, ... -- --- and it supports nil, e.g add_deps("foo", nil, "bar", ...) --- and it also supports to add deps list, e.g. add_deps(deps) +-- and it supports nil, e.g add_orders("foo", nil, "bar", ...) +-- and it also supports to add orders list, e.g. add_orders(orders) -- -function jobgraph:add_deps(...) +function jobgraph:add_orders(...) local prev local prev_is_group local dag = self._dag local jobs = self._jobs local groups = self._groups - local deps = table.pack(...) - local count = deps.n - if count == 1 and type(deps[1]) == "table" then - deps = deps[1] - count = #deps + local orders = table.pack(...) + local count = orders.n + if count == 1 and type(orders[1]) == "table" then + orders = orders[1] + count = #orders end for i = 1, count do - local name = deps[i] + local name = orders[i] if name then local curr_is_group = false local curr = jobs[name] -- cgit v1.3.1 From f55ca39e18390317210ac7d660cbfaa517c1e691 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 27 Mar 2025 23:05:03 +0800 Subject: add jobgraph:group --- tests/modules/async/run_jobgraph.lua | 8 +++++--- xmake/actions/build/target_utils.lua | 21 ++++++++++++--------- xmake/modules/async/jobgraph.lua | 27 +++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 14 deletions(-) (limited to 'tests/modules/async') diff --git a/tests/modules/async/run_jobgraph.lua b/tests/modules/async/run_jobgraph.lua index 9b8f529ed..4463038b7 100644 --- a/tests/modules/async/run_jobgraph.lua +++ b/tests/modules/async/run_jobgraph.lua @@ -33,9 +33,11 @@ function _test_group() jobs:add("job/root", _jobfunc) for i = 1, 3 do jobs:add("job/" .. i, _jobfunc, {groups = "bar"}) - for j = 1, 50 do - jobs:add("job/" .. i .. "/" .. j, _jobfunc, {groups = "foo"}) - end + jobgraph:group("foo", function () + for j = 1, 50 do + jobs:add("job/" .. i .. "/" .. j, _jobfunc) + end + end) end jobs:add_orders("foo", "bar", "job/root") t = os.mclock() diff --git a/xmake/actions/build/target_utils.lua b/xmake/actions/build/target_utils.lua index 41c979b85..13cf54ad9 100644 --- a/xmake/actions/build/target_utils.lua +++ b/xmake/actions/build/target_utils.lua @@ -39,7 +39,6 @@ end function _add_script_job(jobgraph, instance, script_name, scriptcmd_name, opt) opt = opt or {} local joborders = opt.joborders - local group_name = opt.group_name local script = instance:script(script_name) if script then -- call custom script with jobgraph @@ -49,6 +48,7 @@ function _add_script_job(jobgraph, instance, script_name, scriptcmd_name, opt) -- on_build(function (target, jobgraph, opt) -- end, {jobgraph = true}) if instance:extraconf(script_name, "jobgraph") then + -- TODO group and joborders script(target, jobgraph) elseif instance:extraconf(script_name, "batch") then wprint("%s.%s: the batch mode is deprecated, please use jobgraph mode instead of it.", instance:fullname(), script_name) @@ -62,9 +62,11 @@ function _add_script_job(jobgraph, instance, script_name, scriptcmd_name, opt) local jobname = string.format("%s/%s/%s", instance == target and "target" or "rule", instance:fullname(), script_name) jobgraph:add(jobname, function (index, total, opt) script(target, {progress = opt.progress}) - end, {groups = group_name}) + end) table.insert(joborders, jobname) end + elseif false then + -- TODO call builtin script else -- call command script -- e.g. @@ -79,7 +81,7 @@ function _add_script_job(jobgraph, instance, script_name, scriptcmd_name, opt) local batchcmds_ = batchcmds.new({target = target}) scriptcmd(target, batchcmds_, {progress = opt.progress}) batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) - end, {groups = group_name}) + end) table.insert(joborders, jobname) end end @@ -108,12 +110,13 @@ function _add_stage_jobs_for_target(jobgraph, target, stage, opt) -- call target and rules script local joborders = {} - for _, instance in ipairs(instances) do - _add_script_job(jobgraph, instance, script_name, scriptcmd_name, { - group_name = group_name, - joborders = joborders - }) - end + jobgraph:group(group_name, function () + for _, instance in ipairs(instances) do + _add_script_job(jobgraph, instance, script_name, scriptcmd_name, { + joborders = joborders + }) + end + end) -- add job orders if #joborders > 0 then diff --git a/xmake/modules/async/jobgraph.lua b/xmake/modules/async/jobgraph.lua index fe42f6647..b9e9a46da 100644 --- a/xmake/modules/async/jobgraph.lua +++ b/xmake/modules/async/jobgraph.lua @@ -78,8 +78,9 @@ function jobgraph:add(name, run, opt) dag:add_vertex(job) self._size = self._size + 1 - if opt.groups then - for _, group_name in ipairs(opt.groups) do + if self._current_groups or opt.groups then + local job_groups = table.join(self._current_groups or {}, opt.groups) + for _, group_name in ipairs(job_groups) do local groups = self._groups[group_name] if not groups then groups = {} @@ -104,6 +105,28 @@ function jobgraph:remove(name) end end +-- enter group to add jobs +-- +-- e.g. +-- jobgraph:group("foo", function () +-- jobgraph:add("job1", function (index, total, opt) +-- TODO +-- end) +-- jobgraph:add("job2", function (index, total, opt) +-- TODO +-- end) +-- end) +function jobgraph:group(name, callback) + local current_groups = self._current_groups + if current_groups == nil then + current_groups = {} + self._current_groups = current_groups + end + table.insert(current_groups, name) + callback() + table.remove(current_groups) +end + -- add job orders, e.g. add_orders(a, b, c, ...): a -> b -> c, ... -- -- and it supports nil, e.g add_orders("foo", nil, "bar", ...) -- cgit v1.3.1 From 987ab86a6270073e6d1d08d4e8e70d6487e0d65c Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 27 Mar 2025 23:05:19 +0800 Subject: fix test --- tests/modules/async/run_jobgraph.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/modules/async') diff --git a/tests/modules/async/run_jobgraph.lua b/tests/modules/async/run_jobgraph.lua index 4463038b7..fe53a54c6 100644 --- a/tests/modules/async/run_jobgraph.lua +++ b/tests/modules/async/run_jobgraph.lua @@ -33,7 +33,7 @@ function _test_group() jobs:add("job/root", _jobfunc) for i = 1, 3 do jobs:add("job/" .. i, _jobfunc, {groups = "bar"}) - jobgraph:group("foo", function () + jobs:group("foo", function () for j = 1, 50 do jobs:add("job/" .. i .. "/" .. j, _jobfunc) end -- cgit v1.3.1