# 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)
```

### Manual Installation

```bash
git clone https://github.com/synor/compute-sdk-c
cd compute-sdk-c
mkdir build && cd build
cmake ..
make
sudo make install
```

## Quick Start

```c
#include <synor_compute.h>
#include <stdio.h>

int main() {
    // Initialize client
    synor_client_t* client = synor_client_create("your-api-key");
    if (!client) {
        fprintf(stderr, "Failed to create client\n");
        return 1;
    }

    // Create tensors
    size_t shape[] = {512, 512};
    synor_tensor_t* a = synor_tensor_random(shape, 2, SYNOR_FP32);
    synor_tensor_t* b = synor_tensor_random(shape, 2, SYNOR_FP32);

    // Matrix multiplication on GPU
    synor_matmul_options_t opts = {
        .precision = SYNOR_FP16,
        .processor = SYNOR_PROCESSOR_GPU,
        .priority = SYNOR_PRIORITY_NORMAL
    };

    synor_result_t* result = synor_matmul(client, a, b, &opts);
    if (result && result->status == SYNOR_STATUS_COMPLETED) {
        printf("Time: %ldms\n", result->execution_time_ms);
        printf("Cost: $%.6f\n", result->cost);
    }

    // Cleanup
    synor_result_free(result);
    synor_tensor_free(a);
    synor_tensor_free(b);
    synor_client_free(client);

    return 0;
}
```

## Tensor Operations

```c
// Create tensors
size_t shape[] = {3, 3};
synor_tensor_t* zeros = synor_tensor_zeros(shape, 2, SYNOR_FP32);
synor_tensor_t* ones = synor_tensor_ones(shape, 2, SYNOR_FP32);
synor_tensor_t* random = synor_tensor_random(shape, 2, SYNOR_FP32);

// From data
float data[] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f};
size_t data_shape[] = {2, 3};
synor_tensor_t* tensor = synor_tensor_create(data, 6, data_shape, 2, SYNOR_FP32);

// Get tensor info
size_t ndim = synor_tensor_ndim(tensor);
size_t size = synor_tensor_size(tensor);
const size_t* tensor_shape = synor_tensor_shape(tensor);

// Get data pointer
const float* tensor_data = synor_tensor_data(tensor);
```

## Matrix Operations

```c
// Matrix multiplication
synor_matmul_options_t matmul_opts = {
    .precision = SYNOR_FP16,
    .processor = SYNOR_PROCESSOR_GPU
};
synor_result_t* result = synor_matmul(client, a, b, &matmul_opts);

// 2D Convolution
synor_conv2d_options_t conv_opts = {
    .stride_h = 1, .stride_w = 1,
    .padding_h = 1, .padding_w = 1,
    .precision = SYNOR_FP32
};
synor_result_t* conv = synor_conv2d(client, input, kernel, &conv_opts);

// Attention
synor_attention_options_t attn_opts = {
    .num_heads = 8,
    .flash = true,
    .precision = SYNOR_FP16
};
synor_result_t* attn = synor_attention(client, query, key, value, &attn_opts);
```

## LLM Inference

```c
// Single response
synor_inference_options_t opts = {
    .max_tokens = 512,
    .temperature = 0.7f,
    .top_p = 0.9f
};
synor_inference_result_t* response = synor_inference(
    client, "llama-3-70b", "Explain quantum computing", &opts
);
if (response) {
    printf("%s\n", response->result);
    synor_inference_result_free(response);
}

// Streaming with callback
void on_chunk(const char* chunk, void* user_data) {
    printf("%s", chunk);
    fflush(stdout);
}

synor_inference_stream(client, "llama-3-70b", "Write a poem",
    &opts, on_chunk, NULL);
```

## Configuration

```c
synor_config_t config = {
    .api_key = "your-api-key",
    .base_url = "https://api.synor.io/compute/v1",
    .default_processor = SYNOR_PROCESSOR_GPU,
    .default_precision = SYNOR_FP16,
    .timeout_secs = 30,
    .debug = false
};

synor_client_t* client = synor_client_create_with_config(&config);
```

## Error Handling

```c
synor_result_t* result = synor_matmul(client, a, b, &opts);

if (!result) {
    const char* error = synor_get_last_error();
    fprintf(stderr, "Error: %s\n", error);
} else if (result->status == SYNOR_STATUS_FAILED) {
    fprintf(stderr, "Job failed: %s\n", result->error_message);
}

// Check for specific errors
synor_error_t err = synor_get_error_code();
switch (err) {
    case SYNOR_ERROR_NETWORK:
        fprintf(stderr, "Network error\n");
        break;
    case SYNOR_ERROR_AUTH:
        fprintf(stderr, "Authentication failed\n");
        break;
    case SYNOR_ERROR_INVALID_ARG:
        fprintf(stderr, "Invalid argument\n");
        break;
}
```

## Types

```c
// Processor types
typedef enum {
    SYNOR_PROCESSOR_CPU,
    SYNOR_PROCESSOR_GPU,
    SYNOR_PROCESSOR_TPU,
    SYNOR_PROCESSOR_NPU,
    SYNOR_PROCESSOR_LPU,
    SYNOR_PROCESSOR_FPGA,
    SYNOR_PROCESSOR_AUTO
} synor_processor_t;

// Precision
typedef enum {
    SYNOR_FP64,
    SYNOR_FP32,
    SYNOR_FP16,
    SYNOR_BF16,
    SYNOR_INT8,
    SYNOR_INT4
} synor_precision_t;

// Job status
typedef enum {
    SYNOR_STATUS_PENDING,
    SYNOR_STATUS_RUNNING,
    SYNOR_STATUS_COMPLETED,
    SYNOR_STATUS_FAILED,
    SYNOR_STATUS_CANCELLED
} synor_status_t;
```

## Memory Management

All Synor objects must be freed:

```c
synor_tensor_free(tensor);
synor_result_free(result);
synor_inference_result_free(response);
synor_client_free(client);
```

## Thread Safety

The client is thread-safe. Each thread can share the same client instance.

## Requirements

- C99 or later
- libcurl for HTTP
- OpenSSL for TLS

## Building

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

## Testing

```bash
cd build
ctest
```

## License

MIT
