1#![allow(dead_code)]
7
8use crate::c_api::*;
9use std::os::raw::{c_char, c_float, c_int, c_void};
10
11#[no_mangle]
13pub unsafe extern "C" fn ruby_tensor_new(
14 data: *const c_void,
15 shape: *const usize,
16 ndim: usize,
17 dtype: TorshDType,
18) -> *mut TorshTensor {
19 torsh_tensor_new(data, shape, ndim, dtype)
21}
22
23#[no_mangle]
25pub unsafe extern "C" fn ruby_tensor_add(
26 a: *mut TorshTensor,
27 b: *mut TorshTensor,
28 output: *mut TorshTensor,
29) -> TorshError {
30 torsh_tensor_add(a, b, output)
31}
32
33#[no_mangle]
35pub unsafe extern "C" fn ruby_tensor_mul(
36 a: *mut TorshTensor,
37 b: *mut TorshTensor,
38 output: *mut TorshTensor,
39) -> TorshError {
40 torsh_tensor_mul(a, b, output)
41}
42
43#[no_mangle]
45pub unsafe extern "C" fn ruby_tensor_matmul(
46 a: *mut TorshTensor,
47 b: *mut TorshTensor,
48 output: *mut TorshTensor,
49) -> TorshError {
50 torsh_tensor_matmul(a, b, output)
51}
52
53#[no_mangle]
55pub unsafe extern "C" fn ruby_tensor_relu(
56 input: *mut TorshTensor,
57 output: *mut TorshTensor,
58) -> TorshError {
59 torsh_tensor_relu(input, output)
60}
61
62#[no_mangle]
64pub unsafe extern "C" fn ruby_tensor_shape(
65 tensor: *mut TorshTensor,
66 shape: *mut usize,
67 ndim: *mut usize,
68) -> TorshError {
69 torsh_tensor_shape(tensor, shape, ndim)
70}
71
72#[no_mangle]
74pub unsafe extern "C" fn ruby_tensor_data(tensor: *mut TorshTensor) -> *const c_void {
75 torsh_tensor_data(tensor)
76}
77
78#[no_mangle]
80pub unsafe extern "C" fn ruby_tensor_free(tensor: *mut TorshTensor) {
81 torsh_tensor_free(tensor)
82}
83
84#[no_mangle]
86pub unsafe extern "C" fn ruby_linear_new(
87 in_features: usize,
88 out_features: usize,
89 bias: c_int,
90) -> *mut TorshModule {
91 torsh_linear_new(in_features, out_features, bias != 0)
92}
93
94#[no_mangle]
96pub unsafe extern "C" fn ruby_linear_forward(
97 module: *mut TorshModule,
98 input: *mut TorshTensor,
99) -> *mut TorshTensor {
100 let error = torsh_linear_forward(module, input, input);
102 if error != TorshError::Success {
103 return std::ptr::null_mut();
104 }
105
106 input
107}
108
109#[no_mangle]
111pub unsafe extern "C" fn ruby_module_free(module: *mut TorshModule) {
112 torsh_module_free(module)
113}
114
115#[no_mangle]
117pub unsafe extern "C" fn ruby_sgd_new(
118 learning_rate: c_float,
119 momentum: c_float,
120) -> *mut TorshOptimizer {
121 torsh_sgd_new(learning_rate, momentum)
122}
123
124#[no_mangle]
126pub unsafe extern "C" fn ruby_adam_new(
127 learning_rate: c_float,
128 beta1: c_float,
129 beta2: c_float,
130 epsilon: c_float,
131) -> *mut TorshOptimizer {
132 torsh_adam_new(learning_rate, beta1, beta2, epsilon)
133}
134
135#[no_mangle]
137pub unsafe extern "C" fn ruby_optimizer_step(
138 optimizer: *mut TorshOptimizer,
139 _parameters: *mut *mut TorshTensor,
140 _gradients: *mut *mut TorshTensor,
141 _param_count: usize,
142) -> TorshError {
143 torsh_optimizer_step(optimizer)
144}
145
146#[no_mangle]
148pub unsafe extern "C" fn ruby_optimizer_free(optimizer: *mut TorshOptimizer) {
149 torsh_optimizer_free(optimizer)
150}
151
152#[no_mangle]
154pub unsafe extern "C" fn ruby_get_last_error() -> *const c_char {
155 torsh_get_last_error()
156}
157
158#[no_mangle]
160pub unsafe extern "C" fn ruby_clear_last_error() {
161 torsh_clear_last_error()
162}
163
164#[no_mangle]
166pub unsafe extern "C" fn ruby_version() -> *const c_char {
167 torsh_version()
168}
169
170#[no_mangle]
172pub unsafe extern "C" fn ruby_cuda_is_available() -> c_int {
173 torsh_cuda_is_available()
174}
175
176#[no_mangle]
178pub unsafe extern "C" fn ruby_cuda_device_count() -> c_int {
179 torsh_cuda_device_count()
180}
181
182#[cfg(test)]
183mod tests {
184 use super::*;
185
186 #[test]
187 fn test_ruby_tensor_operations() {
188 let data = vec![1.0f32, 2.0, 3.0, 4.0];
190 let shape = vec![2, 2];
191
192 unsafe {
193 let tensor = ruby_tensor_new(
194 data.as_ptr() as *const c_void,
195 shape.as_ptr(),
196 shape.len(),
197 TorshDType::F32,
198 );
199
200 assert!(!tensor.is_null());
201
202 let mut retrieved_shape = vec![0usize; 2];
204 let mut ndim = 0;
205 let result = ruby_tensor_shape(tensor, retrieved_shape.as_mut_ptr(), &mut ndim);
206 assert_eq!(result, TorshError::Success);
207 assert_eq!(ndim, 2);
208 assert_eq!(retrieved_shape, shape);
209
210 ruby_tensor_free(tensor);
212 }
213 }
214
215 #[test]
216 fn test_ruby_module_operations() {
217 unsafe {
218 let linear = ruby_linear_new(4, 2, 1);
220 assert!(!linear.is_null());
221
222 let input_data = vec![1.0f32, 2.0, 3.0, 4.0];
224 let input_shape = vec![1, 4];
225
226 let input_tensor = ruby_tensor_new(
227 input_data.as_ptr() as *const c_void,
228 input_shape.as_ptr(),
229 input_shape.len(),
230 TorshDType::F32,
231 );
232
233 let output = ruby_linear_forward(linear, input_tensor);
234 assert!(!output.is_null());
235
236 ruby_tensor_free(input_tensor);
238 ruby_tensor_free(output);
239 ruby_module_free(linear);
240 }
241 }
242
243 #[test]
244 fn test_ruby_optimizer_operations() {
245 unsafe {
246 let sgd = ruby_sgd_new(0.01, 0.9);
248 assert!(!sgd.is_null());
249
250 let adam = ruby_adam_new(0.001, 0.9, 0.999, 1e-8);
252 assert!(!adam.is_null());
253
254 ruby_optimizer_free(sgd);
256 ruby_optimizer_free(adam);
257 }
258 }
259}