# Project export: HPC: High Phone Computing

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 11.0
- Tagline: The Distributed Global GPU
- Devpost: https://devpost.com/software/hpc-high-phone-computing
- GitHub: https://github.com/ayaviri/calhacks
- Team: 3 GitHub contributor(s) — Kenneth Chap (7 commits), MuuSeoTia (3 commits), Shloak Rathod (1 commits)

## Devpost submission (written by the team)

### Inspiration

With the advancements in AI technology, the energy necessary to train models continues to increase exponentially, and thus both the environmental costs go up considerably. Some ideas have already been put in place for example the Massachusetts Green High Performance Computing Center (MGHPCC) and Google have started building renewable energy farms using solar, wind, and nuclear power. This presents new challenges such as the difficulty of maintenance, costs, and limits to computing thus we came up with a new form of HPC: High Phone Computing!

### What it does

A web server that parallelizes a model’s training procedure and assigns subtasks to iPhones, using their A18 Pro chips with 5 GPU cores. The idea is to use iPhones’ idle compute to train a large GPU-intensive model using a distributed system. A user simply uploads a pre-processed dataset and gets a trained model back! In theory, we save 28.8 to 46.7% in energy consumption. The world has approximately 90 million iPhone 15s and 16s, adding 10 million NVIDIA A100s 40 GB and about $14 Billion in value, assuming each iPhone is rented out for 4 hours per day.

### How we built it

We built this system to enable distributed machine learning model training across multiple iPhones, leveraging their A18 Pro chips for GPU-based computation. The front end was developed using Vue.js, providing an intuitive interface for users to upload models and datasets. A REST API handles the uploads, while Redis Cache optimizes performance by temporarily storing requests and ensuring smooth task queuing. The backend uses a round-robin system to distribute tasks evenly among nodes, preventing any single device from becoming overloaded. A database tracks the status of tasks and manages synchronization across nodes. On the iPhone 16 Pro devices, we implemented a hybrid Rust and JavaScript app. Rust handles performance-critical and security-sensitive operations, while JavaScript manages communication with the backend and local training tasks. Additionally, Nuxt.js with Meta Framework powers each node's local Vue.js-based interfaces. For GPU optimizations, we used Metal Shading Language (MSL) to optimize kernel operations, taking full advantage of the A18 Pro chip's capabilities. The training process utilizes TensorFlow’s multi-threading to split and parallelize tasks across the nodes, with model parallelism enabling the division of large models across multiple devices. Each node processes tensors independently, and the results are synchronized and aggregated to form the final trained model. This synchronization ensures seamless and consistent model performance, regardless of the distributed nature of the computation. Once the training is complete, the system synchronizes the tensors and aggregates the results into a single trained model, which is sent back to the user through the upload portal. This approach leverages high-performance on-device GPU compute with distributed task execution, ensuring both speed and scalability.

### Challenges we ran into

The first and most brutal challenge was the iPhone’s very tight security and running tensorflow on iPhones. Since TensorFlow for Swift was deprecated, we had to create a work around utilizing an unlikely culprit: Tensorflow Javascript specifically through Rust for Javascript as an extension. The next issue was the fact that in order to optimize kernel operations on arm chips, we had to use MSL (Metal Shading Language) for optimizing MPS (Metal Performance Shaders) the equivalent of CUDA for NVIDIA GPUs.

### Accomplishments we're proud of

Overcoming Apple’s sandbox blocking developers from train models on IOS by building a Rust, JavaScript, and Swift application! Splitting, synchronizing, and optimizing a training task into subtasks using Metal Shading Language (MSL), and Keras. Managing multiple iPhone Nodes on a server and assigning tasks.

### What we learned

A lot! We built an IOS application using Rust, JavaScript, Swift, and Nuxt.js—we’ve never used such a combination of tasks and learned it along the way! We built the backend using FastAPI, Postgres, Redis, and RabbitMQ server to ensure an efficient distribution algorithm. Lastly, we split our main model into Shards, allowing parallel training. We combined the multiple tensor outputs from nodes into a single model, using Metal Shading Language and Keras. We’ve never built such a complicated pipeline before with so many different components talking with each other.

### What's next

We’d like to expand and scale our application for other compute tasks such as ray tracing, graphics rendering, and other computationally intensive tasks. Furthermore, we’d like to dynamically allow users to set their idle time and add themselves as “workers.” Lastly, we aim to get every iPhone user on our application and increase the world’s compute by 10 Million NVIDIA A100s 40GB!

## README (from the GitHub repository)

# calhacks
A distributed machine learning model finetuning framework for mobile.


## Detected evidence (automated analysis)

Indexed codebase: 56 recognized source files, 108 KB.
- C (language) — detected in the code
- CSS (language) — detected in the code
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- Rust (language) — detected in the code
- Swift (language) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Vue (technology) — detected in the code
- FastAPI (technology) — claimed on Devpost, not found in the code
- TensorFlow (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (120 of 127)

```
.DS_Store
.gitignore
LICENSE
README.md
services/.DS_Store
services/app_worker/.DS_Store
services/app_worker/.gitignore
services/app_worker/.nuxt/app.config.mjs
services/app_worker/.nuxt/components.d.ts
services/app_worker/.nuxt/dev/index.mjs
services/app_worker/.nuxt/dev/index.mjs.map
services/app_worker/.nuxt/imports.d.ts
services/app_worker/.nuxt/manifest/latest.json
services/app_worker/.nuxt/manifest/meta/dev.json
services/app_worker/.nuxt/nitro.json
services/app_worker/.nuxt/nuxt.d.ts
services/app_worker/.nuxt/nuxt.json
services/app_worker/.nuxt/schema/nuxt.schema.d.ts
services/app_worker/.nuxt/schema/nuxt.schema.json
services/app_worker/.nuxt/tsconfig.json
services/app_worker/.nuxt/tsconfig.server.json
services/app_worker/.nuxt/types/app-defaults.d.ts
services/app_worker/.nuxt/types/app.config.d.ts
services/app_worker/.nuxt/types/build.d.ts
services/app_worker/.nuxt/types/imports.d.ts
services/app_worker/.nuxt/types/middleware.d.ts
services/app_worker/.nuxt/types/nitro-config.d.ts
services/app_worker/.nuxt/types/nitro-imports.d.ts
services/app_worker/.nuxt/types/nitro-nuxt.d.ts
services/app_worker/.nuxt/types/nitro-routes.d.ts
services/app_worker/.nuxt/types/nitro.d.ts
services/app_worker/.nuxt/types/plugins.d.ts
services/app_worker/.nuxt/types/schema.d.ts
services/app_worker/.nuxt/types/vue-shim.d.ts
services/app_worker/app.vue
services/app_worker/assets/css/main.css
services/app_worker/nuxt.config.ts
services/app_worker/package.json
services/app_worker/public/robots.txt
services/app_worker/README.md
services/app_worker/server/tsconfig.json
services/app_worker/src-tauri/.gitignore
services/app_worker/src-tauri/build.rs
services/app_worker/src-tauri/capabilities/default.json
services/app_worker/src-tauri/Cargo.lock
services/app_worker/src-tauri/Cargo.toml
services/app_worker/src-tauri/gen/apple/.DS_Store
services/app_worker/src-tauri/gen/apple/.gitignore
services/app_worker/src-tauri/gen/apple/app_iOS/app_iOS.entitlements
services/app_worker/src-tauri/gen/apple/app_iOS/Info.plist
services/app_worker/src-tauri/gen/apple/app.xcodeproj/project.pbxproj
services/app_worker/src-tauri/gen/apple/app.xcodeproj/project.xcworkspace/contents.xcworkspacedata
services/app_worker/src-tauri/gen/apple/app.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
services/app_worker/src-tauri/gen/apple/app.xcodeproj/xcshareddata/xcschemes/app_iOS.xcscheme
services/app_worker/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json
services/app_worker/src-tauri/gen/apple/Assets.xcassets/Contents.json
services/app_worker/src-tauri/gen/apple/ExportOptions.plist
services/app_worker/src-tauri/gen/apple/LaunchScreen.storyboard
services/app_worker/src-tauri/gen/apple/Podfile
services/app_worker/src-tauri/gen/apple/project.yml
services/app_worker/src-tauri/gen/apple/Sources/app/bindings/bindings.h
services/app_worker/src-tauri/gen/apple/Sources/app/main.mm
services/app_worker/src-tauri/icons/icon.icns
services/app_worker/src-tauri/src/lib.rs
services/app_worker/src-tauri/src/main.rs
services/app_worker/src-tauri/tauri.conf.json
services/app_worker/tailwind.config.js
services/app_worker/tauri-plugin-swift/.gitignore
services/app_worker/tauri-plugin-swift/build.rs
services/app_worker/tauri-plugin-swift/Cargo.toml
services/app_worker/tauri-plugin-swift/guest-js/index.ts
services/app_worker/tauri-plugin-swift/ios/.gitignore
services/app_worker/tauri-plugin-swift/ios/Package.resolved
services/app_worker/tauri-plugin-swift/ios/Package.swift
services/app_worker/tauri-plugin-swift/ios/Sources/ExamplePlugin.swift
services/app_worker/tauri-plugin-swift/package.json
services/app_worker/tauri-plugin-swift/permissions/autogenerated/commands/get_gpu.toml
services/app_worker/tauri-plugin-swift/permissions/autogenerated/commands/graphics.toml
services/app_worker/tauri-plugin-swift/permissions/autogenerated/commands/ping.toml
services/app_worker/tauri-plugin-swift/permissions/autogenerated/reference.md
services/app_worker/tauri-plugin-swift/permissions/default.toml
services/app_worker/tauri-plugin-swift/permissions/ping.toml
services/app_worker/tauri-plugin-swift/permissions/schemas/schema.json
services/app_worker/tauri-plugin-swift/README.md
services/app_worker/tauri-plugin-swift/rollup.config.js
services/app_worker/tauri-plugin-swift/src/commands.rs
services/app_worker/tauri-plugin-swift/src/desktop.rs
services/app_worker/tauri-plugin-swift/src/error.rs
services/app_worker/tauri-plugin-swift/src/lib.rs
services/app_worker/tauri-plugin-swift/src/mobile.rs
services/app_worker/tauri-plugin-swift/src/models.rs
services/app_worker/tauri-plugin-swift/tsconfig.json
services/app_worker/tsconfig.json
services/app_worker/utils/invokeHardware.js
services/app_worker/utils/invokeSwift.js
services/app_worker/utils/runModel.js
services/web_client/.gitignore
services/web_client/app.vue
services/web_client/nuxt.config.ts
services/web_client/package.json
services/web_client/public/robots.txt
services/web_client/README.md
services/web_client/server/tsconfig.json
services/web_client/tsconfig.json
services/worker/.env
services/worker/docker-compose.yaml
services/worker/README.md
workers/.gitignore
workers/data/FashionMNIST/raw/t10k-images-idx3-ubyte
workers/data/FashionMNIST/raw/t10k-labels-idx1-ubyte
workers/data/FashionMNIST/raw/train-images-idx3-ubyte
workers/data/FashionMNIST/raw/train-labels-idx1-ubyte
workers/dummy.py
workers/fashion_mnist_resnet18.pt
workers/mobilenetv2.tflite
workers/saved_model.keras
workers/saved_model/fingerprint.pb
workers/saved_model/saved_model.pb
workers/saved_model/variables/variables.data-00000-of-00001
workers/saved_model/variables/variables.index
[7 more files omitted for size]
```

### Dependencies

- services/app_worker/package.json: @nuxtjs/tailwindcss@^6.12.2, @tauri-apps/cli@^2.0.3, @tauri-apps/plugin-websocket@^2.0.0, @unocss/nuxt@^0.63.4, amqplib@^0.10.4, autoprefixer@^10.4.20, nuxt@^3.13.2, postcss@^8.4.47, stompjs@^2.3.3, tailwindcss@^3.4.14, unocss@^0.63.4, vue@latest, vue-router@latest, vue-writer@^2.0.2
- services/app_worker/src-tauri/Cargo.toml: log@0.4, serde@1.0, serde_json@1.0, tauri@2.0.3, tauri-build@2.0.1, tauri-plugin-log@2.0.0-rc, tauri-plugin-swift, tauri-plugin-websocket@2
- services/app_worker/tauri-plugin-swift/Cargo.toml: serde@1.0, tauri@2.0.3, tauri-plugin@2.0.1, thiserror@1.0
- services/app_worker/tauri-plugin-swift/package.json: @rollup/plugin-typescript@^11.1.6, @tauri-apps/api@>=2.0.0-beta.6, rollup@^4.9.6, tslib@^2.6.2, typescript@^5.3.3
- services/web_client/package.json: axios@^1.7.7, nuxt@^3.13.2, vue@latest, vue-router@latest

### Recent commits (newest first)

- Update README.md
- Update app.vue
- :lipstick: made worker ui prettier
- braced dummy.py for demo
- Updated sharding and syncronization
- :sparkles: fixed?
- Squashed commit of the following:
- App worker (#4)
- :sparkles: added upload and download endpoints (#3)
- Worker branch contains dummy model + dummy data + shard tests  (#2)
- :sparkles: created test form (#1)
- Forgot the web client directory
- Setting up the repository structure and the docker-compose.yaml file for the RabbitMQ server (for the workers)
- Initial commit

## Key source files (fetched from GitHub, selected and truncated for size)

### services/app_worker/tauri-plugin-swift/permissions/autogenerated/reference.md

```markdown
## Default Permission

Default permissions for the plugin

- `allow-ping`

## Permission Table

<table>
<tr>
<th>Identifier</th>
<th>Description</th>
</tr>


<tr>
<td>

`swift:allow-get-gpu`

</td>
<td>

Enables the get_gpu command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`swift:deny-get-gpu`

</td>
<td>

Denies the get_gpu command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`swift:allow-graphics`

</td>
<td>

Enables the graphics command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`swift:deny-graphics`

</td>
<td>

Denies the graphics command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`swift:allow-ping`

</td>
<td>

Enables the ping command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`swift:deny-ping`

</td>
<td>

Denies the ping command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`swift:ping`

</td>
<td>

This enables all file read related
commands without any pre-configured accessible paths.

</td>
</tr>
</table>

```

### services/worker/docker-compose.yaml

```yaml
services:
  amqp:
    image: rabbitmq:latest
    hostname: calhacks-rabbit
    restart: always
    ports:
      - ${RABBIT_PORT}:${RABBIT_PORT}

```

### services/web_client/package.json

```
{
  "name": "nuxt-app",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "dependencies": {
    "axios": "^1.7.7",
    "nuxt": "^3.13.2",
    "vue": "latest",
    "vue-router": "latest"
  }
}

```

### services/app_worker/package.json

```
{
  "name": "nuxt-app",
  "private": true,
  "type": "module",
  "scripts": {
    "tauri": "tauri",
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "dependencies": {
    "@tauri-apps/plugin-websocket": "^2.0.0",
    "amqplib": "^0.10.4",
    "nuxt": "^3.13.2",
    "stompjs": "^2.3.3",
    "vue": "latest",
    "vue-router": "latest",
    "vue-writer": "^2.0.2"
  },
  "devDependencies": {
    "@nuxtjs/tailwindcss": "^6.12.2",
    "@tauri-apps/cli": "^2.0.3",
    "@unocss/nuxt": "^0.63.4",
    "autoprefixer": "^10.4.20",
    "postcss": "^8.4.47",
    "tailwindcss": "^3.4.14",
    "unocss": "^0.63.4"
  }
}

```

### services/app_worker/tauri-plugin-swift/Cargo.toml

```
[package]
name = "tauri-plugin-swift"
version = "0.1.0"
authors = [ "You" ]
description = ""
edition = "2021"
rust-version = "1.77.2"
exclude = ["/examples", "/webview-dist", "/webview-src", "/node_modules"]
links = "tauri-plugin-swift"

[dependencies]
tauri = { version = "2.0.3" }
serde = "1.0"
thiserror = "1.0"

[build-dependencies]
tauri-plugin = { version = "2.0.1", features = ["build"] }


```

### services/app_worker/src-tauri/Cargo.toml

```
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2021"
rust-version = "1.77.2"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]

[build-dependencies]
tauri-build = { version = "2.0.1", features = [] }

[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
log = "0.4"
tauri = { version = "2.0.3", features = [] }
tauri-plugin-log = "2.0.0-rc"
tauri-plugin-swift = { path = "../tauri-plugin-swift" }
tauri-plugin-websocket = "2"


```

### services/app_worker/tauri-plugin-swift/package.json

```
{
  "name": "tauri-plugin-swift-api",
  "version": "0.1.0",
  "author": "You",
  "description": "",
  "type": "module",
  "types": "./dist-js/index.d.ts",
  "main": "./dist-js/index.cjs",
  "module": "./dist-js/index.js",
  "exports": {
    "types": "./dist-js/index.d.ts",
    "import": "./dist-js/index.js",
    "require": "./dist-js/index.cjs"
  },
  "files": [
    "dist-js",
    "README.md"
  ],
  "scripts": {
    "build": "rollup -c",
    "prepublishOnly": "pnpm build",
    "pretest": "pnpm build"
  },
  "dependencies": {
    "@tauri-apps/api": ">=2.0.0-beta.6"
  },
  "devDependencies": {
    "@rollup/plugin-typescript": "^11.1.6",
    "rollup": "^4.9.6",
    "typescript": "^5.3.3",
    "tslib": "^2.6.2"
  }
}

```

### services/app_worker/src-tauri/src/main.rs

```rust
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

fn main() {
    app_lib::run();
}

```

### services/app_worker/tauri-plugin-swift/guest-js/index.ts

```typescript
import { invoke } from '@tauri-apps/api/core'

export async function ping(value: string): Promise<string | null> {
  return await invoke<{value?: string}>('plugin:swift|ping', {
    payload: {
      value,
    },
  }).then((r) => (r.value ? r.value : null));
}

```

### workers/testmodel2.py

```python
import tensorflow as tf

os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'

cifar = tf.keras.datasets.cifar100
(x_train, y_train), (x_test, y_test) = cifar.load_data()
model = tf.keras.applications.ResNet50(
    include_top=True,
    weights=None,
    input_shape=(32, 32, 3),
    classes=100,)

loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)
model.compile(optimizer="adam", loss=loss_fn, metrics=["accuracy"])
model.fit(x_train, y_train, epochs=5, batch_size=64)
```

[45 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]