@@ -272,96 +272,134 @@ namespace hal
272
272
273
273
const MultiBitInformation& Context::get_multi_bit_information ()
274
274
{
275
- if (!m_mbi.has_value ())
275
+ auto mbi = std::atomic_load_explicit (&m_mbi, std::memory_order_acquire);
276
+ if (mbi)
276
277
{
277
- const auto seq_gates = nl->get_gates ([](const auto * g) { return g->get_type ()->has_property (GateTypeProperty::sequential); });
278
- m_mbi = calculate_multi_bit_information (seq_gates);
278
+ return *mbi;
279
279
}
280
+ else
281
+ {
282
+ std::lock_guard<std::mutex> lock (m_mbi_mutex);
283
+ mbi = std::atomic_load_explicit (&m_mbi, std::memory_order_acquire);
284
+ if (mbi)
285
+ {
286
+ return *mbi;
287
+ }
280
288
281
- return m_mbi.value ();
289
+ auto new_mbi = std::make_shared<MultiBitInformation>();
290
+ const auto seq_gates = nl->get_gates ([](const auto * g) { return g->get_type ()->has_property (GateTypeProperty::sequential); });
291
+ *new_mbi = calculate_multi_bit_information (seq_gates);
292
+
293
+ std::atomic_store_explicit (&m_mbi, new_mbi, std::memory_order_release);
294
+
295
+ return *new_mbi;
296
+ }
282
297
}
283
298
284
299
const Result<NetlistAbstraction*> Context::get_sequential_abstraction ()
285
300
{
286
- if (!m_sequential_abstraction.has_value ())
301
+ auto abstraction = std::atomic_load_explicit (&m_sequential_abstraction, std::memory_order_acquire);
302
+ if (abstraction)
287
303
{
304
+ return OK (abstraction.get ());
305
+ }
306
+ else
307
+ {
308
+ std::lock_guard<std::mutex> lock (m_sequential_abstraction_mutex);
309
+ // Double-check after acquiring the lock
310
+ abstraction = std::atomic_load_explicit (&m_sequential_abstraction, std::memory_order_acquire);
311
+ if (abstraction)
312
+ {
313
+ return OK (abstraction.get ());
314
+ }
315
+
288
316
const auto seq_gates = nl->get_gates ([](const auto * g) { return g->get_type ()->has_property (GateTypeProperty::sequential); });
289
317
290
- const std::vector<PinType> forbidden_pins = {
291
- PinType::clock , /* PinType::done, PinType::error, PinType::error_detection,*/ /* PinType::none,*/ PinType::ground, PinType::power /* , PinType::status*/ };
318
+ const std::vector<PinType> forbidden_pins = {PinType::clock , PinType::ground, PinType::power};
292
319
293
- const auto endpoint_filter = [forbidden_pins](const auto * ep, const auto & _d) {
294
- UNUSED (_d);
320
+ const auto endpoint_filter = [forbidden_pins](const auto * ep, const auto &) {
295
321
return std::find (forbidden_pins.begin (), forbidden_pins.end (), ep->get_pin ()->get_type ()) == forbidden_pins.end ();
296
322
};
297
323
298
- const auto sequential_abstraction_res = NetlistAbstraction::create (nl, seq_gates, true , endpoint_filter, endpoint_filter);
324
+ auto sequential_abstraction_res = NetlistAbstraction::create (nl, seq_gates, true , endpoint_filter, endpoint_filter);
299
325
if (sequential_abstraction_res.is_error ())
300
326
{
301
- return ERR_APPEND (sequential_abstraction_res.get_error (), " cannot get sequential netlist abstraction for gate feature context : failed to build abstraction." );
327
+ return ERR_APPEND (sequential_abstraction_res.get_error (), " Cannot get sequential netlist abstraction: failed to build abstraction." );
302
328
}
303
329
304
- m_sequential_abstraction = sequential_abstraction_res.get ();
330
+ auto new_abstraction = sequential_abstraction_res.get ();
305
331
306
- // TODO remove debug print
307
- // std::cout << "Built abstraction" << std::endl;
308
- }
332
+ std::atomic_store_explicit (&m_sequential_abstraction, new_abstraction, std::memory_order_release);
309
333
310
- return OK (&m_sequential_abstraction.value ());
334
+ return OK (m_sequential_abstraction.get ());
335
+ }
311
336
}
312
337
313
338
const Result<NetlistAbstraction*> Context::get_original_abstraction ()
314
339
{
315
- if (!m_original_abstraction.has_value ())
340
+ auto abstraction = std::atomic_load_explicit (&m_original_abstraction, std::memory_order_acquire);
341
+ if (abstraction)
316
342
{
317
- // const std::vector<PinType> forbidden_pins = {
318
- // PinType::clock, /*PinType::done, PinType::error, PinType::error_detection,*/ /*PinType::none,*/ PinType::ground, PinType::power /*, PinType::status*/};
319
-
320
- // const auto endpoint_filter = [forbidden_pins](const auto* ep, const auto& _d) {
321
- // UNUSED(_d);
322
- // return std::find(forbidden_pins.begin(), forbidden_pins.end(), ep->get_pin()->get_type()) == forbidden_pins.end();
323
- // };
343
+ return OK (abstraction.get ());
344
+ }
345
+ else
346
+ {
347
+ std::lock_guard<std::mutex> lock (m_original_abstraction_mutex);
348
+ // Double-check after acquiring the lock
349
+ abstraction = std::atomic_load_explicit (&m_original_abstraction, std::memory_order_acquire);
350
+ if (abstraction)
351
+ {
352
+ return OK (abstraction.get ());
353
+ }
324
354
325
- const auto original_abstraction_res = NetlistAbstraction::create (nl, nl->get_gates (), true , nullptr , nullptr );
355
+ auto original_abstraction_res = NetlistAbstraction::create (nl, nl->get_gates (), true , nullptr , nullptr );
326
356
if (original_abstraction_res.is_error ())
327
357
{
328
- return ERR_APPEND (original_abstraction_res.get_error (), " cannot get original netlist abstraction for gate feature context : failed to build abstraction." );
358
+ return ERR_APPEND (original_abstraction_res.get_error (), " Cannot get original netlist abstraction: failed to build abstraction." );
329
359
}
330
360
331
- m_original_abstraction = original_abstraction_res.get ();
361
+ auto new_abstraction = original_abstraction_res.get ();
332
362
333
- // TODO remove debug print
334
- // std::cout << "Built abstraction" << std::endl;
335
- }
363
+ std::atomic_store_explicit (&m_original_abstraction, new_abstraction, std::memory_order_release);
336
364
337
- return OK (&m_original_abstraction.value ());
365
+ return OK (m_original_abstraction.get ());
366
+ }
338
367
}
339
368
340
369
const std::vector<GateTypeProperty>& Context::get_possible_gate_type_properties ()
341
370
{
342
- if (!m_possible_gate_type_properties.has_value ())
371
+ auto properties = std::atomic_load_explicit (&m_possible_gate_type_properties, std::memory_order_acquire);
372
+ if (properties)
373
+ {
374
+ return *properties;
375
+ }
376
+ else
343
377
{
344
- std::set<GateTypeProperty> properties;
378
+ std::lock_guard<std::mutex> lock (m_possible_gate_type_properties_mutex);
379
+ // Double-check after acquiring the lock
380
+ properties = std::atomic_load_explicit (&m_possible_gate_type_properties, std::memory_order_acquire);
381
+ if (properties)
382
+ {
383
+ return *properties;
384
+ }
385
+
386
+ std::set<GateTypeProperty> property_set;
345
387
346
388
for (const auto & [_name, gt] : nl->get_gate_library ()->get_gate_types ())
347
389
{
348
- const auto gt_properties = gt->get_properties ();
349
- properties .insert (gt_properties.begin (), gt_properties.end ());
390
+ const auto & gt_properties = gt->get_properties ();
391
+ property_set .insert (gt_properties.begin (), gt_properties.end ());
350
392
}
351
393
352
- // for (auto& [gtp, _name] : EnumStrings<GateTypeProperty>::data)
353
- // {
354
- // UNUSED(_name);
355
- // properties.insert(gtp);
356
- // }
394
+ auto properties_vec = std::make_shared<std::vector<GateTypeProperty>>(property_set.begin (), property_set.end ());
357
395
358
- auto properties_vec = utils::to_vector (properties);
359
- // sort alphabetically
360
- std::sort (properties_vec.begin (), properties_vec.end (), [](const auto & a, const auto & b) { return enum_to_string (a) < enum_to_string (b); });
361
- m_possible_gate_type_properties = properties_vec;
362
- }
396
+ // Sort alphabetically
397
+ std::sort (properties_vec->begin (), properties_vec->end (), [](const auto & a, const auto & b) { return enum_to_string (a) < enum_to_string (b); });
363
398
364
- return m_possible_gate_type_properties.value ();
399
+ std::atomic_store_explicit (&m_possible_gate_type_properties, properties_vec, std::memory_order_release);
400
+
401
+ return *properties_vec;
402
+ }
365
403
}
366
404
} // namespace machine_learning
367
405
} // namespace hal
0 commit comments