33# ------------------------------------------------------------------
44
55mutable struct PlatformFeatures
6- default_platform_types_all
7- default_platform_types
8- actual_platform_arguments_all
9- actual_platform_arguments
6+ platform_feature_default_all
7+ platform_feature_default
8+ platform_feature_all
9+ platform_feature
1010 function PlatformFeatures ()
1111 new (Dict (),Dict (),Dict (),Dict ())
1212 end
@@ -28,6 +28,7 @@ defT =[
2828 :node_memory_bandwidth => Tuple{AtLeast0,AtMostInf},
2929 :node_memory_type => MemoryType,
3030 :node_memory_frequency => Tuple{AtLeast1,AtMostInf},
31+ :node_coworker_count => WorkerCount, # number of worker processes (i.e., julia -p N)
3132 :processor_count => Tuple{AtLeast1,AtMostInf},
3233 :processor_manufacturer => Manufacturer,
3334 :processor_microarchitecture => ProcessorMicroarchitecture,
@@ -78,63 +79,101 @@ defT =[
7879 :storage_interface => StorageInterface
7980]
8081
81- state. default_platform_types_all = Dict (defT... )
82- state. default_platform_types = copy (state. default_platform_types_all)
82+ state. platform_feature_default_all = Dict (defT... )
83+ state. platform_feature_default = copy (state. platform_feature_default_all)
84+
85+ function setupWorkers (platform_description_dict, platform_feature)
86+ try
87+ colocated_procs = procs (myid ())
88+
89+ node_coworker_count = if (1 in colocated_procs)
90+ length (colocated_procs) - 1
91+ else
92+ length (colocated_procs)
93+ end
94+
95+ vcount = platform_description_dict[:node_vcpus_count ]
96+ pcount = platform_description_dict[:processor_count ]
97+ ccount = pcount * platform_description_dict[:processor_core_count ]
98+ tcount = ccount * platform_description_dict[:processor_core_threads_count ]
99+
100+ if vcount == node_coworker_count && platform_description_dict[:maintainer ] == CloudProvider
101+ platform_feature[:node_coworker_count ] = PerVCPU
102+ elseif (node_coworker_count = 0 )
103+ platform_feature[:node_coworker_count ] = NoCoworkers
104+ elseif node_coworker_count == 1
105+ platform_feature[:node_coworker_count ] = PerNode
106+ elseif pcount == node_coworker_count
107+ platform_feature[:node_coworker_count ] = PerProcessor
108+ elseif ccount == node_coworker_count
109+ platform_feature[:node_coworker_count ] = PerCore
110+ elseif tcount == node_coworker_count
111+ platform_feature[:node_coworker_count ] = PerThread
112+ else
113+ platform_feature[:node_coworker_count ] = Unmapped
114+ end
115+ catch _
116+ platform_feature[:node_coworker_count ] = NoCoworkers
117+ end
118+ end
83119
84120function load! ()
85- empty! (state. actual_platform_arguments_all )
121+ empty! (state. platform_feature_all )
86122 platform_description_dict = readPlatormDescription ()
87- loadFeatures! (platform_description_dict, state. default_platform_types_all, state. actual_platform_arguments_all)
123+ platform_description_dict[" node" ][" node_count" ] = try Distributed. nworkers () catch _ 1 end
124+ loadFeatures! (platform_description_dict, state. platform_feature_default_all, state. platform_feature_all)
125+
126+ setupWorkers (platform_description_dict, state. platform_feature_all)
88127
89- empty! (state. actual_platform_arguments )
90- for (k,v) in state. actual_platform_arguments_all
91- state. actual_platform_arguments [k] = v
128+ empty! (state. platform_feature )
129+ for (k,v) in state. platform_feature_all
130+ state. platform_feature [k] = v
92131 end
93132end
94133
95134# load!()
96135
97136function setplatform! (parameter_id, actual_type)
98- state. actual_platform_arguments [parameter_id] = actual_type
137+ state. platform_feature [parameter_id] = actual_type
99138 (parameter_id,actual_type)
100139end
101140
102141function getplatform (parameter_id)
103- state. actual_platform_arguments [parameter_id]
142+ state. platform_feature [parameter_id]
104143end
105144
106145function getplatform ()
107- state. actual_platform_arguments
146+ state. platform_feature
108147end
109148
110- function empty_actual_platform_arguments ! ()
111- empty! (state. actual_platform_arguments )
112- empty! (state. default_platform_types )
149+ function empty_platform_feature ! ()
150+ empty! (state. platform_feature )
151+ empty! (state. platform_feature_default )
113152end
114153
115- function reset_actual_platform_arguments ! ()
116- for (k,v) in state. actual_platform_arguments_all
117- state. actual_platform_arguments [k] = v
154+ function reset_platform_feature ! ()
155+ for (k,v) in state. platform_feature_all
156+ state. platform_feature [k] = v
118157 end
119158 for (k,v) in platform_types_all
120- state. default_platform_types [k] = v
159+ state. platform_feature_default [k] = v
121160 end
122- keys (state. actual_platform_arguments )
161+ keys (state. platform_feature )
123162end
124163
125164function include_actual_platform_argument! (f)
126- state. actual_platform_arguments [f] = state. actual_platform_arguments_all [f]
127- state. default_platform_types [f] = state. default_platform_types_all [f]
128- keys (state. actual_platform_arguments )
165+ state. platform_feature [f] = state. platform_feature_all [f]
166+ state. platform_feature_default [f] = state. platform_feature_default_all [f]
167+ keys (state. platform_feature )
129168end
130169
131170
132171function platform_parameter_macro! (f)
133172
134173 if (f == :clear )
135- empty_actual_platform_arguments ! ()
174+ empty_platform_feature ! ()
136175 elseif (f == :all )
137- reset_actual_platform_arguments ! ()
176+ reset_platform_feature ! ()
138177 else
139178 check_all (f)
140179 include_actual_platform_argument! (f)
@@ -149,24 +188,24 @@ function platform_parameters_kernel(p_list)
149188
150189 # replace default types to required types in kernel platform parameters
151190 r = []
152- for k in keys (state. actual_platform_arguments )
191+ for k in keys (state. platform_feature )
153192 found = get (p_dict, k, nothing )
154- v = state. default_platform_types [k]
193+ v = state. platform_feature_default [k]
155194 push! (r, isnothing (found) ? :(:: Type{<:$v} ) : :(:: Type{<:$found} ))
156195 end
157196
158197 return r
159198end
160199
161200function check_all (parameter_id)
162- if (! haskey (state. actual_platform_arguments_all ,parameter_id))
201+ if (! haskey (state. platform_feature_all ,parameter_id))
163202 throw (parameter_id)
164203 end
165204 parameter_id
166205end
167206
168207function check (parameter_id)
169- if (! haskey (state. actual_platform_arguments ,parameter_id))
208+ if (! haskey (state. platform_feature ,parameter_id))
170209 throw (parameter_id)
171210 end
172211 parameter_id
@@ -225,7 +264,7 @@ function build_entry_signature(fsign::Expr)
225264 keyword_parameters = length (call_node_args) > 1 && typeof (call_node_args[1 ]) == Expr && call_node_args[1 ]. head == :parameters ? popfirst! (call_node_args). args : []
226265 # takes a dictionary mapping par->actual_type and returns an expression :(par::actual_type)
227266 # the remaining elements in call_node_args are the kernel parameters.
228- platform_parameters = map (p-> Expr (:kw ,Expr (:(:: ),p[1 ],Type{<: state.default_platform_types [p[1 ]]}),p[2 ]), collect (state. actual_platform_arguments ))
267+ platform_parameters = map (p-> Expr (:kw ,Expr (:(:: ),p[1 ],Type{<: state.platform_feature_default [p[1 ]]}),p[2 ]), collect (state. platform_feature ))
229268 # rebuild the keyword parameters node for the entry function, including the platform_parameters
230269 keyword_parameters_node = Expr (:parameters , platform_parameters... , keyword_parameters... )
231270 # collect the identifiers of the kernel parameters
239278
240279function build_entry_body (fname, fargs, kargs)
241280 # takes the identifiers of the platform parameters
242- pargs = keys (state. actual_platform_arguments )
281+ pargs = keys (state. platform_feature )
243282 # builds the :parameters node for the keyword arguments of the kernel invocation (kargs), since the identifiers must be refferenced.
244283 kargs = Expr (:parameters , map (p -> Expr (:kw , p, p), kargs)... )
245284 # returns the :call node for the kernel invocation (note that platform arguments comes before kernel arguments)
0 commit comments