diff --git a/torchao/experimental/benchmark_infra/ios/Entitlements-Dev.plist b/torchao/experimental/benchmark_infra/ios/Entitlements-Dev.plist
new file mode 100644
index 000000000..62ac51a1e
--- /dev/null
+++ b/torchao/experimental/benchmark_infra/ios/Entitlements-Dev.plist
@@ -0,0 +1,12 @@
+
+
+
+
+ get-task-allow
+
+ keychain-access-groups
+
+ T84QZS65DQ.platformFamily
+
+
+
diff --git a/torchao/experimental/benchmark_infra/ios/TorchAOBenchmark-Info.plist b/torchao/experimental/benchmark_infra/ios/TorchAOBenchmark-Info.plist
new file mode 100644
index 000000000..75f73ad24
--- /dev/null
+++ b/torchao/experimental/benchmark_infra/ios/TorchAOBenchmark-Info.plist
@@ -0,0 +1,34 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleDisplayName
+ ${PRODUCT_NAME}
+ CFBundleExecutable
+ ${EXECUTABLE_NAME}
+ CFBundleIdentifier
+ ${FB_BUNDLE_ID}
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ ${PRODUCT_NAME}
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+
+
+
diff --git a/torchao/experimental/benchmark_infra/ios/main_empty.mm b/torchao/experimental/benchmark_infra/ios/main_empty.mm
new file mode 100644
index 000000000..e7a2c5d33
--- /dev/null
+++ b/torchao/experimental/benchmark_infra/ios/main_empty.mm
@@ -0,0 +1,8 @@
+// (c) Meta Platforms, Inc. and affiliates.
+
+#include
+
+int main(int argc, char** argv) {
+ std::cout << "Default main when no benchmarking deps are specified\n";
+ return 0;
+}
diff --git a/torchao/experimental/benchmark_infra/ios/output_redirect.h b/torchao/experimental/benchmark_infra/ios/output_redirect.h
new file mode 100644
index 000000000..e69de29bb
diff --git a/torchao/experimental/benchmark_infra/ios/output_redirect.mm b/torchao/experimental/benchmark_infra/ios/output_redirect.mm
new file mode 100644
index 000000000..1e7f6def5
--- /dev/null
+++ b/torchao/experimental/benchmark_infra/ios/output_redirect.mm
@@ -0,0 +1,44 @@
+// (c) Meta Platforms, Inc. and affiliates.
+
+#import "output_redirect.h"
+
+#import
+#import
+#import
+#import
+
+#import
+
+class STDIORedirector {
+ public:
+ STDIORedirector() {
+ if (@available(iOS 17, *)) {
+ /* duplicate stdout */
+ std::string file_name =
+ std::string(std::getenv("HOME")) + "/tmp/BENCH_LOG";
+ redirect_out_ = fopen(file_name.c_str(), "w");
+ stdout_dupfd_ = dup(1);
+ /* replace stdout with our output fd */
+ dup2(fileno(redirect_out_), 1);
+ fflush(stdout);
+ setvbuf(stdout, nil, _IONBF, 0);
+ setvbuf(redirect_out_, nil, _IONBF, 0);
+ }
+ }
+
+ ~STDIORedirector() {
+ if (@available(iOS 17, *)) {
+ fflush(stdout);
+ /* restore stdout */
+ dup2(stdout_dupfd_, 1);
+ close(stdout_dupfd_);
+ fclose(redirect_out_);
+ }
+ }
+
+ private:
+ FILE* redirect_out_;
+ int stdout_dupfd_;
+};
+
+static STDIORedirector stdio_redirector_;
diff --git a/torchao/experimental/benchmark_infra/test/test_bench.cpp b/torchao/experimental/benchmark_infra/test/test_bench.cpp
new file mode 100644
index 000000000..474d29f7d
--- /dev/null
+++ b/torchao/experimental/benchmark_infra/test/test_bench.cpp
@@ -0,0 +1,49 @@
+// (c) Meta Platforms, Inc. and affiliates.
+
+#include
+
+#include
+#include
+#include
+#include
+
+namespace {
+std::random_device rd;
+std::mt19937 generator(rd());
+
+// This test is to validate that the benchmarking binary
+// can be run on any device. Right now, it is focusing
+// on benchmarking on laptop (x86 oe mac) and iOS
+static void TestBenchmark(benchmark::State& state) {
+ const int32_t K = state.range(0);
+ auto a = std::make_unique(K);
+ auto b = std::make_unique(K);
+ auto c = std::make_unique(K);
+ static std::uniform_real_distribution<> real_distrib(-1.0, 1.0);
+ for (int ii = 0; ii < K; ++ii) {
+ a[ii] = real_distrib(generator);
+ b[ii] = real_distrib(generator);
+ c[ii] = 0;
+ }
+ for (auto _ : state) {
+ for (int ii = 0; ii < K; ++ii) {
+ c[ii] = a[ii] + b[ii];
+ }
+ }
+}
+
+BENCHMARK(TestBenchmark)->Args({4096 * 4})->UseRealTime();
+} // namespace
+
+int main(int argc, char** argv) {
+ char arg0_default[] = "benchmark";
+ char* args_default = arg0_default;
+ if (!argv) {
+ argc = 1;
+ argv = &args_default;
+ }
+ ::benchmark::Initialize(&argc, argv);
+ ::benchmark::RunSpecifiedBenchmarks();
+ ::benchmark::Shutdown();
+ return 0;
+}