Skip to content

Commit 692dcb1

Browse files
Merge pull request #28 from PlatformAwareProgramming/exact_quantifiers
adding support for quantifiers carrying exact numeric values
2 parents d124132 + 6d15784 commit 692dcb1

7 files changed

Lines changed: 85 additions & 44 deletions

File tree

src/PlatformAware.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ end
5151

5252
export
5353
@platform,
54+
@quantifier,
5455
@atleast,
5556
@atmost,
5657
@between,

src/features/features.jl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,34 +112,39 @@ end
112112
function get_quantifier_from_number(n)
113113

114114
if n>0
115-
116115
magnitude = Dict(0 => "", 1 => "K", 2 => "M", 3 => "G", 4 => "T", 5 => "P", 6 => "E")
117116

118117
l = log(2,n)
119-
a = round(l)
118+
a = floor(l)
120119
b = isinteger(l) ? a : a + 1;
121120

122121
# the following loop separates a and b in multiplier*magnitude (see the POPL's paper).
123122

124123
# let A = 2^a
125-
m=0
124+
m1=0
126125
while a>9
127126
# loop invariant: A = 2^a * 2^(10*m)
128127
a = a - 10
128+
m1 = m1 + 1
129+
end
130+
131+
m2=0
132+
while b>9
133+
# loop invariant: A = 2^a * 2^(10*m)
129134
b = b - 10
130-
m = m + 1
135+
m2 = m2 + 1
131136
end
132137

133-
a_str = "AtLeast" * string(Integer(2^a)) * magnitude[m]
134-
b_str = "AtMost" * string(Integer(2^b)) * magnitude[m]
138+
a_str = "AtLeast" * string(Integer(2^a)) * magnitude[m1]
139+
b_str = "AtMost" * string(Integer(2^b)) * magnitude[m2]
135140
else
136141
a_str = "AtLeast0"
137142
b_str = "AtMost0"
138143
end
139144

140145
a_type = getfield(@__MODULE__, Meta.parse(a_str))
141146
b_type = getfield(@__MODULE__, Meta.parse(b_str))
142-
Tuple{a_type,b_type}
147+
Tuple{a_type,b_type,n}
143148
end
144149

145150

src/features/quantifiers/atleast.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
# automated declaration of at-least quantifier types
66

7-
abstract type AtLeast0 <: QuantifierFeature end
7+
abstract type AtLeast0 <: QuantifierFeature end; export AtLeast0
88

99
let mul_super = 0
1010
mag_ = ""

src/features/quantifiers/atmost.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
# automated declaration of at-most quantifier types
77

8-
abstract type AtMostInf <: QuantifierFeature end
8+
abstract type AtMostInf <: QuantifierFeature end; export AtMostInf
99

1010
let mul_super = "Inf" ,
1111
mag_ = "" ;
@@ -15,13 +15,14 @@ let mul_super = "Inf" ,
1515
nm1 = Symbol("AtMost" * string(mul) * mag)
1616
nm2 = Symbol("AtMost" * string(mul_super) * mag_super)
1717
@eval abstract type $nm1 <: $nm2 end
18+
@eval export $nm1
1819
mul_super = mul
1920
end
2021
mag_ = mag
2122
end
2223
end
2324

24-
abstract type AtMost0 <: AtMost1n end
25+
abstract type AtMost0 <: AtMost1n end; export AtMost0
2526

2627

2728

src/features/quantifiers/macros.jl

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,52 @@
22
# Licensed under the MIT License. See LICENCE in the project root.
33
# ------------------------------------------------------------------
44

5+
macro quantifier(n)
6+
get_quantifier(n)
7+
end
8+
59
macro atleast(n)
610
N = n==:∞ || n==:inf ? "AtLeastInf" : "AtLeast" * string(n)
7-
Meta.parse("Tuple{" * N * ",AtMostInf}")
11+
Meta.parse("Type{<:Tuple{$N,AtMostInf,X} where X}")
12+
end
13+
14+
macro atleast(n,x)
15+
N = n==:∞ || n==:inf ? "AtLeastInf" : "AtLeast" * string(n)
16+
esc(Meta.parse("Type{<:Tuple{$N,AtMostInf,$(x)}}"))
817
end
918

1019
macro atmost(n)
1120
N = n==:∞ || n==:inf ? "AtMostInf" : "AtMost" * string(n);
12-
Meta.parse("Tuple{AtLeast0," * N * "}")
21+
Meta.parse("Type{<:Tuple{AtLeast0,$N,X} where X}")
22+
end
23+
24+
macro atmost(n,x)
25+
N = n==:∞ || n==:inf ? "AtMostInf" : "AtMost" * string(n);
26+
Meta.parse("Type{<:Tuple{AtLeast0,$N,$(x)}}")
1327
end
1428

1529
macro between(m,n)
1630
M = m==:∞ || n==:inf ? "AtLeastInf" : "AtLeast" * string(m)
1731
N = n==:∞ || n==:inf ? "AtMostInf" : "AtMost" * string(n)
18-
Meta.parse("Tuple{" * M * "," * N * "}")
32+
Meta.parse("Type{<:Tuple{$M,$N,X} where X}")
33+
end
34+
35+
macro between(m,n,x)
36+
M = m==:∞ || n==:inf ? "AtLeastInf" : "AtLeast" * string(m)
37+
N = n==:∞ || n==:inf ? "AtMostInf" : "AtMost" * string(n)
38+
Meta.parse("Type{<:Tuple{$M,$N,$(x)}}")
1939
end
2040

2141
macro just(m)
2242
M = m==:∞ || m==:inf ? "AtLeastInf" : "AtLeast" * string(m)
2343
N = m==:∞ || m==:inf ? "AtMostInf" : "AtMost" * string(m)
24-
Meta.parse("Tuple{" * M * "," * N * "}")
44+
Meta.parse("Type{<:Tuple{$M,$N,X} where X}")
45+
end
46+
47+
macro just(m,x)
48+
M = m==:∞ || m==:inf ? "AtLeastInf" : "AtLeast" * string(m)
49+
N = m==:∞ || m==:inf ? "AtMostInf" : "AtMost" * string(m)
50+
Meta.parse("Type{<:Tuple{$M,$N,$(x)}}")
2551
end
2652

2753
macro unrestricted()

src/platform.jl

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,65 +16,65 @@ state = PlatformFeatures()
1616

1717

1818
defT =[
19-
:node_count => Tuple{AtLeast1,AtMostInf},
19+
:node_count => Tuple{AtLeast1,AtMostInf,Q} where Q,
2020
:node_provider => Provider,
2121
:node_virtual => Query,
2222
:node_dedicated => Query,
2323
:node_machinefamily => MachineFamily,
2424
:node_machinetype => MachineType,
25-
:node_vcpus_count => Tuple{AtLeast1,AtMostInf},
26-
:node_memory_size => Tuple{AtLeast0,AtMostInf},
27-
:node_memory_latency => Tuple{AtLeast0,AtMostInf},
28-
:node_memory_bandwidth => Tuple{AtLeast0,AtMostInf},
25+
:node_vcpus_count => Tuple{AtLeast1,AtMostInf,Q} where Q,
26+
:node_memory_size => Tuple{AtLeast0,AtMostInf,Q} where Q,
27+
:node_memory_latency => Tuple{AtLeast0,AtMostInf,Q} where Q,
28+
:node_memory_bandwidth => Tuple{AtLeast0,AtMostInf,Q} where Q,
2929
:node_memory_type => MemoryType,
30-
:node_memory_frequency => Tuple{AtLeast1,AtMostInf},
30+
:node_memory_frequency => Tuple{AtLeast1,AtMostInf,Q} where Q,
3131
:node_coworker_count => WorkerCount, # number of worker processes (i.e., julia -p N)
32-
:processor_count => Tuple{AtLeast1,AtMostInf},
32+
:processor_count => Tuple{AtLeast1,AtMostInf,Q} where Q,
3333
:processor_manufacturer => Manufacturer,
3434
:processor_microarchitecture => ProcessorMicroarchitecture,
3535
:processor_simd => ProcessorSIMD,
3636
:processor_isa => ProcessorISA,
37-
:processor_tdp => Tuple{AtLeast0,AtMostInf},
38-
:processor_core_clock => Tuple{AtLeast0,AtMostInf},
39-
:processor_core_count => Tuple{AtLeast1,AtMostInf},
40-
:processor_core_threads_count => Tuple{AtLeast1,AtMostInf},
37+
:processor_tdp => Tuple{AtLeast0,AtMostInf,Q} where Q,
38+
:processor_core_clock => Tuple{AtLeast0,AtMostInf,Q} where Q,
39+
:processor_core_count => Tuple{AtLeast1,AtMostInf,Q} where Q,
40+
:processor_core_threads_count => Tuple{AtLeast1,AtMostInf,Q} where Q,
4141
# :processor_core_L1_mapping => :PC1M,
42-
:processor_core_L1_size => Tuple{AtLeast0,AtMostInf},
42+
:processor_core_L1_size => Tuple{AtLeast0,AtMostInf,Q} where Q,
4343
# :processor_core_L1_latency => :PC1T,
4444
# :processor_core_L1_bandwidth => :PC1B,
4545
# :processor_core_L1_linesize => :PC1L,
4646
# :processor_core_L2_mapping => :PC2M,
47-
:processor_core_L2_size => Tuple{AtLeast0,AtMostInf},
47+
:processor_core_L2_size => Tuple{AtLeast0,AtMostInf,Q} where Q,
4848
# :processor_core_L2_latency => :PC2T,
4949
# :processor_core_L2_bandwidth => :PC2B,
5050
# :processor_core_L2_linesize => :PC2L,
5151
# :processor_L3_mapping => :PC3M,
52-
:processor_L3_size => Tuple{AtLeast0,AtMostInf},
52+
:processor_L3_size => Tuple{AtLeast0,AtMostInf,Q} where Q,
5353
# :processor_L3_latency => :PC3T,
5454
# :processor_L3_bandwidth => :PC3B,
5555
# :processor_L3_linesize => :PC3L,
5656
:processor => Processor,
57-
:accelerator_count => Tuple{AtLeast0,AtMostInf},
57+
:accelerator_count => Tuple{AtLeast0,AtMostInf,Q} where Q,
5858
:accelerator_type => AcceleratorType,
5959
:accelerator_manufacturer => Manufacturer,
6060
:accelerator_api => Tuple{AcceleratorBackend,AcceleratorBackend,AcceleratorBackend,AcceleratorBackend,AcceleratorBackend,AcceleratorBackend,AcceleratorBackend},
6161
:accelerator_architecture => AcceleratorArchitecture,
62-
:accelerator_memory_size => Tuple{AtLeast0,AtMostInf},
63-
:accelerator_tdp => Tuple{AtLeast0,AtMostInf},
62+
:accelerator_memory_size => Tuple{AtLeast0,AtMostInf,Q} where Q,
63+
:accelerator_tdp => Tuple{AtLeast0,AtMostInf,Q} where Q,
6464
:accelerator_processor => AcceleratorProcessor,
65-
:accelerator_processor_count => Tuple{AtLeast1,AtMostInf},
65+
:accelerator_processor_count => Tuple{AtLeast1,AtMostInf,Q} where Q,
6666
:accelerator_memory_type => MemoryType,
6767
:accelerator => Accelerator,
68-
:interconnection_startuptime => Tuple{AtLeast0,AtMostInf},
69-
:interconnection_latency => Tuple{AtLeast0,AtMostInf},
70-
:interconnection_bandwidth => Tuple{AtLeast0,AtMostInf},
68+
:interconnection_startuptime => Tuple{AtLeast0,AtMostInf,Q} where Q,
69+
:interconnection_latency => Tuple{AtLeast0,AtMostInf,Q} where Q,
70+
:interconnection_bandwidth => Tuple{AtLeast0,AtMostInf,Q} where Q,
7171
:interconnection_topology => InterconnectionTopology,
7272
:interconnection_RDMA => Query,
7373
:interconnection => Interconnection,
74-
:storage_size => Tuple{AtLeast0,AtMostInf},
75-
:storage_latency => Tuple{AtLeast0,AtMostInf},
76-
:storage_bandwidth => Tuple{AtLeast0,AtMostInf},
77-
:storage_networkbandwidth => Tuple{AtLeast0,AtMostInf},
74+
:storage_size => Tuple{AtLeast0,AtMostInf,Q} where Q,
75+
:storage_latency => Tuple{AtLeast0,AtMostInf,Q} where Q,
76+
:storage_bandwidth => Tuple{AtLeast0,AtMostInf,Q} where Q,
77+
:storage_networkbandwidth => Tuple{AtLeast0,AtMostInf,Q} where Q,
7878
:storage_type => StorageType,
7979
:storage_interface => StorageInterface
8080
]
@@ -190,8 +190,9 @@ function platform_parameters_kernel(p_list)
190190
r = []
191191
for k in keys(state.platform_feature)
192192
found = get(p_dict, k, nothing)
193+
found_v = !isnothing(found) && !(typeof(found) == Symbol) && ((found.head == :curly && length(found.args) == 2 && found.args[1] == :Type) || (found.head == :macrocall && length(found.args) > 0 && found.args[1] in [Symbol("@atleast"), Symbol("@atmost"), Symbol("@between"), Symbol("@just"), Symbol("@unrestricted")])) ? :(::$found) : :(::Type{<:$found})
193194
v = state.platform_feature_default[k]
194-
push!(r, isnothing(found) ? :(::Type{<:$v}) : :(::Type{<:$found}))
195+
push!(r, isnothing(found) ? :(::Type{<:$v}) : found_v)
195196
end
196197

197198
return r

test/basics.jl

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,17 @@
3030
x,y,args...; z=1, kwargs...)
3131
println(z,": kernel for 1 accelerators of unspecified kind")
3232
end
33-
@platform aware function kernel({accelerator_count::(@atleast 1),
33+
@platform aware function kernel({accelerator_count::@atleast(1,C),
34+
accelerator_manufacturer::NVIDIA,
35+
accelerator_api::(@api CUDA 3.0)},
36+
x::@atleast(1),y,args...; z=2, kwargs...) where C
37+
println(z,": kernel 1 for $C NVIDIA accelerators")
38+
end
39+
@platform aware function kernel({accelerator_count::@atleast(1,C),
3440
accelerator_manufacturer::NVIDIA,
3541
accelerator_api::(@api CUDA 3.0)},
36-
x,y,args...; z=2, kwargs...)
37-
println(z,": kernel for 1 NVIDIA accelerators")
42+
x::@atleast(16),y,args...; z=2, kwargs...) where C
43+
println(z,": kernel 2 for $C NVIDIA accelerators")
3844
end
3945
@platform aware function kernel({node_count::(@atleast 32),
4046
processor::IntelCore_i7_7500U},
@@ -69,6 +75,7 @@
6975
println(z,": a processor with AVX512 SIMD support, and 256GB of primary memory.")
7076
end
7177

72-
kernel(0,1,2,3;z=10,kwargs=0)
78+
kernel(@quantifier(7),1,2,3;z=10,kwargs=0)
79+
kernel(@quantifier(18),1,2,3;z=10,kwargs=0)
7380

7481
end

0 commit comments

Comments
 (0)