microsoft/qdk
Publicmirrored fromhttps://github.com/microsoft/qdkAvailable
compiler/qsc/benches/rca.rs
161lines · modecode
| 1 | // Copyright (c) Microsoft Corporation. |
| 2 | // Licensed under the MIT License. |
| 3 | |
| 4 | use criterion::{criterion_group, criterion_main, Criterion}; |
| 5 | use qsc::incremental::Compiler; |
| 6 | use qsc_data_structures::{language_features::LanguageFeatures, target::TargetCapabilityFlags}; |
| 7 | use qsc_fir::fir::PackageStore; |
| 8 | use qsc_frontend::compile::{PackageStore as HirPackageStore, SourceMap}; |
| 9 | use qsc_lowerer::{map_hir_package_to_fir, Lowerer}; |
| 10 | use qsc_passes::PackageType; |
| 11 | use qsc_rca::{Analyzer, PackageStoreComputeProperties}; |
| 12 | |
| 13 | const TELEPORT: &str = include_str!("../../../samples/algorithms/Teleportation.qs"); |
| 14 | const DEUTSCHJOZSA: &str = include_str!("../../../samples/algorithms/DeutschJozsa.qs"); |
| 15 | const LARGE: &str = include_str!("./large.qs"); |
| 16 | |
| 17 | pub fn core_and_std(c: &mut Criterion) { |
| 18 | c.bench_function( |
| 19 | "Perform Runtime Capabilities Analysis (RCA) on the core and std libraries", |
| 20 | |b| { |
| 21 | let mut compilation_context = CompilationContext::new(); |
| 22 | b.iter(|| { |
| 23 | compilation_context.analyze_all(); |
| 24 | }); |
| 25 | }, |
| 26 | ); |
| 27 | } |
| 28 | |
| 29 | pub fn teleport(c: &mut Criterion) { |
| 30 | c.bench_function( |
| 31 | "Perform Runtime Capabilities Analysis (RCA) on teleport sample", |
| 32 | |b| { |
| 33 | // First, compile and analyze the packages included by default (core & std). |
| 34 | let mut compilation_context = CompilationContext::new(); |
| 35 | compilation_context.analyze_all(); |
| 36 | |
| 37 | // Now, update the compilation with the sample, and analyze only the updated package. |
| 38 | compilation_context.update_compilation(TELEPORT); |
| 39 | b.iter(|| { |
| 40 | compilation_context.analyze_open_package(); |
| 41 | }); |
| 42 | }, |
| 43 | ); |
| 44 | } |
| 45 | |
| 46 | pub fn deutsch_jozsa(c: &mut Criterion) { |
| 47 | c.bench_function( |
| 48 | "Perform Runtime Capabilities Analysis (RCA) on Deutsch-Jozsa sample", |
| 49 | |b| { |
| 50 | // First, compile and analyze the packages included by default (core & std). |
| 51 | let mut compilation_context = CompilationContext::new(); |
| 52 | compilation_context.analyze_all(); |
| 53 | |
| 54 | // Now, update the compilation with the sample, and analyze only the updated package. |
| 55 | compilation_context.update_compilation(DEUTSCHJOZSA); |
| 56 | b.iter(|| { |
| 57 | compilation_context.analyze_open_package(); |
| 58 | }); |
| 59 | }, |
| 60 | ); |
| 61 | } |
| 62 | |
| 63 | pub fn large_file(c: &mut Criterion) { |
| 64 | c.bench_function( |
| 65 | "Perform Runtime Capabilities Analysis (RCA) on large file sample", |
| 66 | |b| { |
| 67 | // First, compile and analyze the packages included by default (core & std). |
| 68 | let mut compilation_context = CompilationContext::new(); |
| 69 | compilation_context.analyze_all(); |
| 70 | |
| 71 | // Now, update the compilation with the sample, and analyze only the updated package. |
| 72 | compilation_context.update_compilation(LARGE); |
| 73 | b.iter(|| { |
| 74 | compilation_context.analyze_open_package(); |
| 75 | }); |
| 76 | }, |
| 77 | ); |
| 78 | } |
| 79 | |
| 80 | struct CompilationContext { |
| 81 | compiler: Compiler, |
| 82 | lowerer: Lowerer, |
| 83 | fir_store: PackageStore, |
| 84 | compute_properties: Option<PackageStoreComputeProperties>, |
| 85 | } |
| 86 | |
| 87 | impl CompilationContext { |
| 88 | fn new() -> Self { |
| 89 | Self::default() |
| 90 | } |
| 91 | |
| 92 | fn analyze_all(&mut self) { |
| 93 | let analyzer = Analyzer::init(&self.fir_store); |
| 94 | let compute_properties = analyzer.analyze_all(); |
| 95 | self.compute_properties = Some(compute_properties); |
| 96 | } |
| 97 | |
| 98 | fn analyze_open_package(&mut self) { |
| 99 | let Some(compute_properties) = &mut self.compute_properties else { |
| 100 | panic!("cannot analyze open package if the other packages have not been analyzed"); |
| 101 | }; |
| 102 | |
| 103 | // Clear the compute properties of the open package. |
| 104 | let open_package_id = map_hir_package_to_fir(self.compiler.package_id()); |
| 105 | let package_compute_properties = compute_properties.get_mut(open_package_id); |
| 106 | package_compute_properties.clear(); |
| 107 | |
| 108 | // Analyze the open package without re-analyzing the other packages. |
| 109 | let analyzer = |
| 110 | Analyzer::init_with_compute_properties(&self.fir_store, compute_properties.clone()); |
| 111 | self.compute_properties = Some(analyzer.analyze_package(open_package_id)); |
| 112 | } |
| 113 | |
| 114 | fn update_compilation(&mut self, source: &str) { |
| 115 | let increment = self |
| 116 | .compiler |
| 117 | .compile_fragments_fail_fast("rca-test", source) |
| 118 | .expect("code should compile"); |
| 119 | let package_id = map_hir_package_to_fir(self.compiler.package_id()); |
| 120 | let fir_package = self.fir_store.get_mut(package_id); |
| 121 | self.lowerer |
| 122 | .lower_and_update_package(fir_package, &increment.hir); |
| 123 | self.compiler.update(increment); |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | impl Default for CompilationContext { |
| 128 | fn default() -> Self { |
| 129 | let (std_id, store) = qsc::compile::package_store_with_stdlib(TargetCapabilityFlags::all()); |
| 130 | let compiler = Compiler::new( |
| 131 | SourceMap::default(), |
| 132 | PackageType::Lib, |
| 133 | TargetCapabilityFlags::all(), |
| 134 | LanguageFeatures::default(), |
| 135 | store, |
| 136 | &[(std_id, None)], |
| 137 | ) |
| 138 | .expect("should be able to create a new compiler"); |
| 139 | let fir_store = lower_hir_package_store(compiler.package_store()); |
| 140 | Self { |
| 141 | compiler, |
| 142 | lowerer: Lowerer::new(), |
| 143 | fir_store, |
| 144 | compute_properties: None, |
| 145 | } |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | fn lower_hir_package_store(hir_package_store: &HirPackageStore) -> PackageStore { |
| 150 | let mut fir_store = PackageStore::new(); |
| 151 | for (id, unit) in hir_package_store { |
| 152 | fir_store.insert( |
| 153 | map_hir_package_to_fir(id), |
| 154 | Lowerer::new().lower_package(&unit.package, &fir_store), |
| 155 | ); |
| 156 | } |
| 157 | fir_store |
| 158 | } |
| 159 | |
| 160 | criterion_group!(benches, core_and_std, teleport, deutsch_jozsa, large_file); |
| 161 | criterion_main!(benches); |
| 162 | |