# Synor Compute SDK for C++

Access distributed heterogeneous compute at 90% cost reduction.

## Installation

### Using CMake

```cmake
find_package(SynorCompute REQUIRED)
target_link_libraries(your_app PRIVATE synor::compute)
```

### vcpkg

```bash
vcpkg install synor-compute
```

### Conan

```
[requires]
synor-compute/0.1.0
```

## Quick Start

```cpp
#include <synor/compute.hpp>
#include <iostream>

int main() {
    synor::Client client("your-api-key");

    // Matrix multiplication on GPU
    auto a = synor::Tensor::random({512, 512});
    auto b = synor::Tensor::random({512, 512});

    auto result = client.matmul(a, b)
        .precision(synor::Precision::FP16)
        .processor(synor::ProcessorType::GPU)
        .execute();

    if (result.isSuccess()) {
        std::cout << "Time: " << result.executionTimeMs() << "ms\n";
        std::cout << "Cost: $" << result.cost() << "\n";
    }

    return 0;
}
```

## Modern C++ Features

### Auto Type Deduction

```cpp
auto tensor = synor::Tensor::random({10, 10});
auto result = client.matmul(a, b).execute();
```

### Structured Bindings (C++17)

```cpp
auto [success, data, error] = client.matmul(a, b).execute();
if (success) {
    std::cout << "Result shape: " << data.shape() << "\n";
}
```

### std::optional Results

```cpp
if (auto time = result.executionTimeMs()) {
    std::cout << "Execution time: " << *time << "ms\n";
}
```

## Tensor Operations

```cpp
// Create tensors
auto zeros = synor::Tensor::zeros({3, 3});
auto ones = synor::Tensor::ones({2, 2});
auto random = synor::Tensor::random({10, 10});
auto randn = synor::Tensor::randn({100});
auto eye = synor::Tensor::eye(3);

// From std::vector
std::vector<float> data = {1, 2, 3, 4, 5, 6};
auto tensor = synor::Tensor(data, {2, 3});

// From initializer list
auto tensor2 = synor::Tensor({1.0f, 2.0f, 3.0f}, {3});

// Operations
auto reshaped = tensor.reshape({3, 2});
auto transposed = tensor.transpose();

// Math
float mean = tensor.mean();
float sum = tensor.sum();
float std_dev = tensor.std();
```

## Builder Pattern API

```cpp
// Matrix multiplication
auto result = client.matmul(a, b)
    .precision(synor::Precision::FP16)
    .processor(synor::ProcessorType::GPU)
    .priority(synor::Priority::High)
    .strategy(synor::Strategy::Speed)
    .execute();

// 2D Convolution
auto conv = client.conv2d(input, kernel)
    .stride(1, 1)
    .padding(1, 1)
    .execute();

// Attention
auto attention = client.attention(query, key, value)
    .numHeads(8)
    .flash(true)
    .execute();
```

## Async API with std::future

```cpp
#include <future>

auto future = client.matmul(a, b)
    .precision(synor::Precision::FP16)
    .executeAsync();

// Do other work...

auto result = future.get();
```

## LLM Inference

```cpp
// Single response
auto response = client.inference("llama-3-70b", "Explain quantum computing")
    .maxTokens(512)
    .temperature(0.7)
    .execute();

std::cout << response.result().value_or("") << "\n";

// Streaming with callback
client.inferenceStream("llama-3-70b", "Write a poem",
    [](std::string_view chunk) {
        std::cout << chunk << std::flush;
    });
```

## Configuration

```cpp
synor::Config config;
config.apiKey = "your-api-key";
config.baseUrl = "https://api.synor.io/compute/v1";
config.defaultProcessor = synor::ProcessorType::GPU;
config.defaultPrecision = synor::Precision::FP16;
config.timeout = std::chrono::seconds(30);
config.debug = true;

synor::Client client(config);
```

## Error Handling

```cpp
try {
    auto result = client.matmul(a, b).execute();
} catch (const synor::ApiError& e) {
    std::cerr << "API Error " << e.statusCode() << ": " << e.what() << "\n";
} catch (const synor::NetworkError& e) {
    std::cerr << "Network error: " << e.what() << "\n";
} catch (const synor::InvalidArgumentError& e) {
    std::cerr << "Invalid argument: " << e.what() << "\n";
}

// Or with std::expected (C++23)
auto result = client.matmul(a, b).tryExecute();
if (result) {
    std::cout << "Success!\n";
} else {
    std::cerr << "Error: " << result.error().message() << "\n";
}
```

## Types

```cpp
// Processor types
enum class ProcessorType {
    CPU, GPU, TPU, NPU, LPU, FPGA, Auto
};

// Precision
enum class Precision {
    FP64, FP32, FP16, BF16, INT8, INT4
};

// Job status
enum class JobStatus {
    Pending, Running, Completed, Failed, Cancelled
};
```

## RAII Memory Management

All Synor objects use RAII:

```cpp
{
    auto tensor = synor::Tensor::random({100, 100});
    auto result = client.matmul(tensor, tensor).execute();
} // Automatic cleanup
```

## Move Semantics

Efficient moves for large tensors:

```cpp
auto tensor = synor::Tensor::random({1000, 1000});
auto moved = std::move(tensor);  // No copy
```

## Thread Safety

The client is thread-safe. Use shared_ptr for multi-threaded access:

```cpp
auto client = std::make_shared<synor::Client>("your-api-key");

// Multiple threads can use client safely
std::thread t1([&client]() { client->matmul(a, b).execute(); });
std::thread t2([&client]() { client->matmul(c, d).execute(); });
```

## Requirements

- C++17 or later
- CMake 3.16+
- libcurl
- nlohmann/json

## Building

```bash
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
```

## Testing

```bash
cd build
ctest --output-on-failure
```

## License

MIT
