Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
Hercules
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
llvm
Hercules
Commits
dc54b81b
Commit
dc54b81b
authored
1 year ago
by
Aaron Councilman
Browse files
Options
Downloads
Patches
Plain Diff
Start implementing new scheduling language
parent
4feea45d
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
juno_scheduler/src/lib.rs
+81
-47
81 additions, 47 deletions
juno_scheduler/src/lib.rs
with
81 additions
and
47 deletions
juno_scheduler/src/lib.rs
+
81
−
47
View file @
dc54b81b
...
@@ -3,6 +3,7 @@ extern crate hercules_ir;
...
@@ -3,6 +3,7 @@ extern crate hercules_ir;
use
std
::
collections
::{
HashSet
,
HashMap
};
use
std
::
collections
::{
HashSet
,
HashMap
};
use
std
::
fs
::
File
;
use
std
::
fs
::
File
;
use
std
::
io
::
Read
;
use
std
::
io
::
Read
;
use
std
::
ops
::{
Index
,
IndexMut
};
use
lrlex
::
DefaultLexerTypes
;
use
lrlex
::
DefaultLexerTypes
;
use
lrpar
::
NonStreamingLexer
;
use
lrpar
::
NonStreamingLexer
;
...
@@ -74,90 +75,119 @@ pub fn schedule(module : &Module, info : FunctionMap, schedule : String)
...
@@ -74,90 +75,119 @@ pub fn schedule(module : &Module, info : FunctionMap, schedule : String)
}
}
}
}
#[derive(Clone)]
struct
DeviceSchedules
{
cpu
:
Vec
<
Schedule
>
,
gpu
:
Vec
<
Schedule
>
,
}
impl
DeviceSchedules
{
fn
new
()
->
Self
{
DeviceSchedules
{
cpu
:
vec!
[],
gpu
:
vec!
[]
}
}
}
impl
Index
<
Device
>
for
DeviceSchedules
{
type
Output
=
Vec
<
Schedule
>
;
fn
index
(
&
self
,
device
:
Device
)
->
&
Self
::
Output
{
match
device
{
Device
::
CPU
=>
&
self
.cpu
,
Device
::
GPU
=>
&
self
.gpu
,
}
}
}
impl
IndexMut
<
Device
>
for
DeviceSchedules
{
fn
index_mut
(
&
mut
self
,
device
:
Device
)
->
&
mut
Self
::
Output
{
match
device
{
Device
::
CPU
=>
&
mut
self
.cpu
,
Device
::
GPU
=>
&
mut
self
.gpu
,
}
}
}
// a plan that tracks additional information useful while we construct the
// a plan that tracks additional information useful while we construct the
// schedule
// schedule
struct
TempPlan
{
struct
TempPlan
{
schedules
:
Vec
<
Vec
<
Schedule
>
>
,
schedules
:
Vec
<
Device
Schedule
s
>
,
// we track both the partition each node is in and what labeled caused us
// we track both the partition each node is in and what labeled caused us
// to assign that partition
// to assign that partition
partitions
:
Vec
<
(
usize
,
PartitionNumber
)
>
,
partitions
:
Vec
<
(
usize
,
PartitionNumber
)
>
,
partition_devices
:
Vec
<
Device
>
,
partition_devices
:
Vec
<
Vec
<
Device
>
>
,
}
}
type
PartitionNumber
=
usize
;
type
PartitionNumber
=
usize
;
impl
Into
<
Plan
>
for
TempPlan
{
fn
generate_schedule
(
module
:
&
Module
,
info
:
FunctionMap
,
schedule
:
Vec
<
parser
::
Partition
>
,
fn
into
(
self
)
->
Plan
{
let
TempPlan
{
schedules
,
partitions
,
partition_devices
}
=
self
;
let
num_partitions
=
partition_devices
.len
();
Plan
{
schedules
:
schedules
,
partitions
:
partitions
.into_iter
()
.map
(|(
_
,
p
)|
PartitionID
::
new
(
p
))
.collect
::
<
Vec
<
_
>>
(),
partition_devices
:
partition_devices
,
num_partitions
:
num_partitions
,
}
}
}
fn
generate_schedule
(
module
:
&
Module
,
info
:
FunctionMap
,
schedule
:
Vec
<
parser
::
Inst
>
,
lexer
:
&
dyn
NonStreamingLexer
<
DefaultLexerTypes
<
u32
>>
)
lexer
:
&
dyn
NonStreamingLexer
<
DefaultLexerTypes
<
u32
>>
)
->
Result
<
HashMap
<
FunctionID
,
Plan
>
,
String
>
{
->
Result
<
HashMap
<
FunctionID
,
Plan
>
,
String
>
{
let
mut
res
:
HashMap
<
FunctionID
,
TempPlan
>
=
HashMap
::
new
();
let
mut
res
:
HashMap
<
FunctionID
,
TempPlan
>
=
HashMap
::
new
();
// we initialize every node in every function as not having any schedule
// and being in the default partition which is a cpu partition (a result of
// We initialize every node in every function as not having any schedule
// label 0)
// and being in the default partition which is a CPU-only partition
// (a result of label 0)
for
(
_
,
(
_
,
_
,
func_insts
))
in
info
.iter
()
{
for
(
_
,
(
_
,
_
,
func_insts
))
in
info
.iter
()
{
for
(
_
,
func_id
,
_
,
_
)
in
func_insts
.iter
()
{
for
(
_
,
func_id
,
_
,
_
)
in
func_insts
.iter
()
{
let
num_nodes
=
module
.functions
[
func_id
.idx
()]
.nodes
.len
();
let
num_nodes
=
module
.functions
[
func_id
.idx
()]
.nodes
.len
();
res
.insert
(
*
func_id
,
res
.insert
(
*
func_id
,
TempPlan
{
TempPlan
{
schedules
:
vec!
[
vec!
[]
;
num_nodes
],
schedules
:
vec!
[
DeviceSchedules
::
new
()
;
num_nodes
],
partitions
:
vec!
[(
0
,
0
);
num_nodes
],
partitions
:
vec!
[(
0
,
0
);
num_nodes
],
partition_devices
:
vec!
[
Device
::
CPU
]
});
partition_devices
:
vec!
[
vec!
[
Device
::
CPU
]
]
});
}
}
}
}
// Construct a map from function names to function numbers
let
mut
function_names
:
HashMap
<
String
,
usize
>
=
HashMap
::
new
();
let
mut
function_names
:
HashMap
<
String
,
usize
>
=
HashMap
::
new
();
for
(
num
,
(
_
,
nm
,
_
))
in
info
.iter
()
{
for
(
num
,
(
_
,
nm
,
_
))
in
info
.iter
()
{
function_names
.insert
(
nm
.clone
(),
*
num
);
function_names
.insert
(
nm
.clone
(),
*
num
);
}
}
// Make the map immutable
let
function_names
=
function_names
;
let
function_names
=
function_names
;
for
parser
::
Inst
{
span
:
_
,
base
,
commands
}
in
schedule
{
for
parser
::
Partition
{
span
:
_
,
func
,
labels
,
directs
}
in
schedule
{
let
parser
::
Func
{
span
:
_
,
name
:
func_name
,
args
:
func_args
}
// Identify the function we are partitioning/scheduling
=
match
&
base
{
let
parser
::
Func
{
span
:
_
,
name
:
func_name
,
args
:
func_args
}
=
func
;
parser
::
Base
::
Function
{
span
:
_
,
func
}
=>
func
,
let
name
=
lexer
.span_str
(
func_name
)
.to_string
();
parser
::
Base
::
Label
{
span
:
_
,
func
,
..
}
=>
func
,
};
let
name
=
lexer
.span_str
(
*
func_name
)
.to_string
();
let
func_num
=
match
function_names
.get
(
&
name
)
{
let
func_num
=
match
function_names
.get
(
&
name
)
{
Some
(
num
)
=>
num
,
Some
(
num
)
=>
num
,
None
=>
{
return
Err
(
format!
(
"Function {} is undefined"
,
name
));
},
None
=>
{
return
Err
(
format!
(
"Function {} is undefined"
,
name
));
},
};
};
if
func_args
.is_some
()
{
if
func_args
.is_some
()
{
todo!
(
"Scheduling particular typed variants not supported"
)
todo!
(
"Scheduling particular typed variants not supported"
)
}
}
// Identify label information
let
(
label_map
,
_
,
func_inst
)
=
info
.get
(
func_num
)
.unwrap
();
let
(
label_map
,
_
,
func_inst
)
=
info
.get
(
func_num
)
.unwrap
();
let
label_num
=
let
get_label_num
=
|
label_span
|
{
match
&
base
{
let
label_name
=
lexer
.span_str
(
label_span
)
.to_string
();
parser
::
Base
::
Function
{
..
}
=>
0
,
match
label_map
.get
(
&
label_name
)
{
parser
::
Base
::
Label
{
span
:
_
,
func
:
_
,
label
}
=>
{
Some
(
num
)
=>
Ok
(
*
num
),
let
label_name
=
lexer
.span_str
(
*
label
)
.to_string
();
None
=>
{
Err
(
format!
(
"Label {} undefined in {}"
,
label_name
,
name
))
},
match
label_map
.get
(
&
label_name
)
{
}
Some
(
num
)
=>
*
num
,
};
None
=>
{
let
label_nums
=
labels
.into_iter
()
.map
(
get_label_num
)
return
Err
(
format!
(
"Label {} undefined in {}"
,
.collect
::
<
HashSet
<
_
>>
();
label_name
,
name
));
},
}
},
};
// Process the partitioning and scheduling directives for each instance
// of the function
for
(
_
,
func_id
,
label_info
,
node_labels
)
in
func_inst
{
for
(
_
,
func_id
,
label_info
,
node_labels
)
in
func_inst
{
// Setup the new partition
let
func_info
=
res
.get_mut
(
func_id
)
.unwrap
();
let
partition_num
=
func_info
.partition_devices
.len
();
let
mut
partition_devices
=
vec!
[];
// Need some sort of recursive process directives function which
// can take information about what devices, or conditions, etc.
for
directive
in
directs
.iter
()
{
match
directive
{
parser
::
Directive
::
OnDevice
{
span
,
device
,
directs
}
=>
{},
parser
::
Directive
::
IfExpr
{
span
,
cond
,
directs
}
=>
{},
parser
::
Directive
::
Command
{
span
,
label
,
commands
}
=>
{},
}
}
/*
for parser::Command { span : _, name : command_name,
for parser::Command { span : _, name : command_name,
args : command_args } in commands.iter() {
args : command_args } in commands.iter() {
if command_args.len() != 0 { todo!("Command arguments not supported") }
if command_args.len() != 0 { todo!("Command arguments not supported") }
...
@@ -203,8 +233,12 @@ fn generate_schedule(module : &Module, info : FunctionMap, schedule : Vec<parser
...
@@ -203,8 +233,12 @@ fn generate_schedule(module : &Module, info : FunctionMap, schedule : Vec<parser
return Err(format!("Command {} undefined", command));
return Err(format!("Command {} undefined", command));
}
}
}
}
*/
func_info
.partition_devices
.push
(
partition_devices
);
}
}
}
}
Ok
(
res
.into_iter
()
.map
(|(
f
,
p
)|
(
f
,
p
.into
()))
.collect
::
<
HashMap
<
_
,
_
>>
())
Err
(
format!
(
"Scheduler not implemented"
))
//Ok(res.into_iter().map(|(f, p)| (f, p.into())).collect::<HashMap<_, _>>())
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment