kinfer 0.5.3__cp311-cp311-macosx_11_0_arm64.whl → 0.5.4__cp311-cp311-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kinfer/rust/src/model.rs CHANGED
@@ -129,9 +129,12 @@ impl ModelRunner {
129
129
  std::fs::create_dir_all(log_dir_path)?;
130
130
  }
131
131
 
132
- // Generate a timestamped filename
133
- let timestamp = chrono::Utc::now().format("%Y-%m-%d_%H-%M-%S").to_string();
134
- let log_file_path = log_dir_path.join(format!("{}.ndjson", timestamp));
132
+ // Use uuid if found, otherwise timestamp
133
+ let log_name = std::env::var("KINFER_LOG_UUID").unwrap_or_else(|_| {
134
+ chrono::Utc::now().format("%Y-%m-%d_%H-%M-%S").to_string()
135
+ });
136
+
137
+ let log_file_path = log_dir_path.join(format!("{}.ndjson", log_name));
135
138
 
136
139
  Some(StepLogger::new(log_file_path).map(Arc::new)?)
137
140
  } else {
@@ -17,6 +17,19 @@ use std::sync::Mutex;
17
17
 
18
18
  type StepResult = (Py<PyArrayDyn<f32>>, Py<PyArrayDyn<f32>>);
19
19
 
20
+ // Custom error type for Send/Sync compatibility
21
+ #[derive(Debug)]
22
+ struct SendError(String);
23
+
24
+ unsafe impl Send for SendError {}
25
+ unsafe impl Sync for SendError {}
26
+
27
+ impl std::fmt::Display for SendError {
28
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29
+ write!(f, "{}", self.0)
30
+ }
31
+ }
32
+
20
33
  #[pyfunction]
21
34
  #[gen_stub_pyfunction]
22
35
  fn get_version() -> String {
@@ -204,9 +217,15 @@ impl ModelProviderABC {
204
217
  metadata: PyModelMetadata,
205
218
  ) -> PyResult<()> {
206
219
  let n = action.len()?;
207
- assert_eq!(metadata.joint_names.len(), n); // TODO: this is wrong
220
+ if metadata.joint_names.len() != n {
221
+ return Err(PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
222
+ "Expected {} joints, got {} action elements",
223
+ metadata.joint_names.len(),
224
+ n
225
+ )));
226
+ }
208
227
  Err(PyNotImplementedError::new_err(format!(
209
- "Must override take_action with {} action",
228
+ "Must override take_action with {} action elements",
210
229
  n
211
230
  )))
212
231
  }
@@ -286,6 +305,7 @@ impl ModelProvider for PyModelProvider {
286
305
  #[derive(Clone)]
287
306
  struct PyModelRunner {
288
307
  runner: Arc<ModelRunner>,
308
+ runtime: Arc<tokio::runtime::Runtime>,
289
309
  }
290
310
 
291
311
  #[gen_stub_pymethods]
@@ -295,7 +315,11 @@ impl PyModelRunner {
295
315
  fn __new__(model_path: String, provider: Py<ModelProviderABC>) -> PyResult<Self> {
296
316
  let input_provider = Arc::new(PyModelProvider::__new__(provider));
297
317
 
298
- let runner = tokio::runtime::Runtime::new()?.block_on(async {
318
+ // Create a single runtime to be reused for all operations
319
+ let runtime = Arc::new(tokio::runtime::Runtime::new()
320
+ .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?);
321
+
322
+ let runner = runtime.block_on(async {
299
323
  ModelRunner::new(model_path, input_provider)
300
324
  .await
301
325
  .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))
@@ -303,17 +327,27 @@ impl PyModelRunner {
303
327
 
304
328
  Ok(Self {
305
329
  runner: Arc::new(runner),
330
+ runtime,
306
331
  })
307
332
  }
308
333
 
334
+ // Reuse runtime and release GIL
309
335
  fn init(&self) -> PyResult<Py<PyArrayDyn<f32>>> {
310
336
  let runner = self.runner.clone();
311
- let result = tokio::runtime::Runtime::new()?.block_on(async {
312
- runner
313
- .init()
314
- .await
315
- .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))
316
- })?;
337
+ let runtime = self.runtime.clone();
338
+
339
+ let result = Python::with_gil(|py| {
340
+ // Release GIL during async operation
341
+ py.allow_threads(|| {
342
+ runtime.block_on(async {
343
+ runner
344
+ .init()
345
+ .await
346
+ .map_err(|e| SendError(e.to_string()))
347
+ })
348
+ })
349
+ })
350
+ .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.0))?;
317
351
 
318
352
  Python::with_gil(|py| {
319
353
  let array = numpy::PyArray::from_array(py, &result);
@@ -321,20 +355,31 @@ impl PyModelRunner {
321
355
  })
322
356
  }
323
357
 
358
+ // Reuse runtime and release GIL
324
359
  fn step(&self, carry: Py<PyArrayDyn<f32>>) -> PyResult<StepResult> {
325
360
  let runner = self.runner.clone();
361
+ let runtime = self.runtime.clone();
362
+
363
+ // Extract the carry array from Python with GIL
326
364
  let carry_array = Python::with_gil(|py| -> PyResult<Array<f32, IxDyn>> {
327
365
  let carry_array = carry.bind(py);
328
366
  Ok(carry_array.to_owned_array())
329
367
  })?;
330
368
 
331
- let result = tokio::runtime::Runtime::new()?.block_on(async {
332
- runner
333
- .step(carry_array)
334
- .await
335
- .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))
336
- })?;
369
+ // Release GIL during computation
370
+ let result = Python::with_gil(|py| {
371
+ py.allow_threads(|| {
372
+ runtime.block_on(async {
373
+ runner
374
+ .step(carry_array)
375
+ .await
376
+ .map_err(|e| SendError(e.to_string()))
377
+ })
378
+ })
379
+ })
380
+ .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.0))?;
337
381
 
382
+ // Reacquire the GIL to convert results back to Python objects
338
383
  Python::with_gil(|py| {
339
384
  let (output, carry) = result;
340
385
  let output_array = numpy::PyArray::from_array(py, &output);
@@ -343,19 +388,29 @@ impl PyModelRunner {
343
388
  })
344
389
  }
345
390
 
391
+ // Reuse runtime and release GIL
346
392
  fn take_action(&self, action: Py<PyArrayDyn<f32>>) -> PyResult<()> {
347
393
  let runner = self.runner.clone();
394
+ let runtime = self.runtime.clone();
395
+
396
+ // Extract action data with GIL
348
397
  let action_array = Python::with_gil(|py| -> PyResult<Array<f32, IxDyn>> {
349
398
  let action_array = action.bind(py);
350
399
  Ok(action_array.to_owned_array())
351
400
  })?;
352
-
353
- tokio::runtime::Runtime::new()?.block_on(async {
354
- runner
355
- .take_action(action_array)
356
- .await
357
- .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))
358
- })?;
401
+
402
+ // Release GIL during computation
403
+ Python::with_gil(|py| {
404
+ py.allow_threads(|| {
405
+ runtime.block_on(async {
406
+ runner
407
+ .take_action(action_array)
408
+ .await
409
+ .map_err(|e| SendError(e.to_string()))
410
+ })
411
+ })
412
+ })
413
+ .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.0))?;
359
414
 
360
415
  Ok(())
361
416
  }
@@ -428,4 +483,4 @@ fn rust_bindings(m: &Bound<PyModule>) -> PyResult<()> {
428
483
  Ok(())
429
484
  }
430
485
 
431
- define_stub_info_gatherer!(stub_info);
486
+ define_stub_info_gatherer!(stub_info);
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kinfer
3
- Version: 0.5.3
3
+ Version: 0.5.4
4
4
  Summary: Tool to make it easier to run a model on a real robot
5
5
  Home-page: https://github.com/kscalelabs/kinfer.git
6
6
  Author: K-Scale Labs
@@ -56,3 +56,8 @@ Dynamic: summary
56
56
  This package is designed to support running real-time robotics models.
57
57
 
58
58
  For more information, see the documentation [here](https://docs.kscale.dev/docs/k-infer).
59
+
60
+ To enable logging, set your log path in the environment variable `KINFER_LOG_PATH`. For example,
61
+ ```
62
+ export KINFER_LOG_PATH=/home/dpsh/kinfer-logs
63
+ ```
@@ -1,4 +1,4 @@
1
- kinfer/rust_bindings.cpython-311-darwin.so,sha256=_5fj6xtOIO5izMvTAfcMhomH88qK-YF5Ha7K-z9BLjs,2089040
1
+ kinfer/rust_bindings.cpython-311-darwin.so,sha256=fD5BrTQku9NU8aSKSwM8NcaxbU8nDArMveNYG5kj_q8,2071856
2
2
  kinfer/requirements.txt,sha256=e8RzCNVZGJ9Jb874Eom0psUCOqp0wGf8LJZ86ysto0w,127
3
3
  kinfer/__init__.py,sha256=i5da6ND827Cgn8PFKzDCmEBk14ptQasLa_9fdof4Y9c,398
4
4
  kinfer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -8,7 +8,7 @@ kinfer/rust/src/runtime.rs,sha256=7BRZmyMoV6FvYs2_XnLk0DFrxt7qgz35loCUJRSsuxM,34
8
8
  kinfer/rust/src/logger.rs,sha256=5Uvv60zp6HV4zmaD9bA1vENDtE19uYrRzA-xRY26bl8,4124
9
9
  kinfer/rust/src/types.rs,sha256=wNLlXXmGmcE7uF4tKuZ7ChRy9-PI-JWq2iuh7diQS_g,3187
10
10
  kinfer/rust/src/lib.rs,sha256=25LuAdONp9c3lI0_g2kAf73yrtzbYc9GtJjm1zl9IwU,120
11
- kinfer/rust/src/model.rs,sha256=q7y4tWf_Ivi1seG73vJIGOcptnEWEIy0dj0RZaT4CtA,12085
11
+ kinfer/rust/src/model.rs,sha256=WluovJlgKSrAlAOkKlhhiVnD-OhN9E6xznZRPn2LFFI,12176
12
12
  kinfer/scripts/plot_ndjson.py,sha256=eg-wwuDLRDcuVdr1Jc5W4yeJG5Bf--UjaK6kk9XoC4w,6179
13
13
  kinfer/export/serialize.py,sha256=QjsvTn7cIRroZXXONXQUrEd1tR69oLrszojuKoK-Xuk,3208
14
14
  kinfer/export/__init__.py,sha256=6a8cClA2H3AAjAhY6ucmxEnfCRZ30FDn2L7SArCu7nY,56
@@ -17,10 +17,10 @@ kinfer/export/pytorch.py,sha256=nRo9TKClRhPcLJQDR3oHNCbTYjf_3gLBxGfzZBScPxc,1303
17
17
  kinfer/rust_bindings/Cargo.toml,sha256=i1RGB9VNd9Q4FJ6gGwjZJQYo8DBBvpVWf3GJ95EfVgM,637
18
18
  kinfer/rust_bindings/pyproject.toml,sha256=jLcJuHCnQRh9HWR_R7a9qLHwj6LMBgnHyeKK_DruO1Y,135
19
19
  kinfer/rust_bindings/rust_bindings.pyi,sha256=lPGHMDsydr4Ue-CNHRjQtJWmq5sE5daVN8PbxJgOZY4,2048
20
- kinfer/rust_bindings/src/lib.rs,sha256=Uqi76Na_fGiecMeW5mSSmtYdz2wU8clLxYawbYomNOc,12662
20
+ kinfer/rust_bindings/src/lib.rs,sha256=f5TBqP6tYmb3vXQiisCsxAPB37_mtoaZSFvc_FlOeKY,14473
21
21
  kinfer/rust_bindings/src/bin/stub_gen.rs,sha256=hhoVGnaSfazbSfj5a4x6mPicGPOgWQAfsDmiPej0B6Y,133
22
- kinfer-0.5.3.dist-info/RECORD,,
23
- kinfer-0.5.3.dist-info/WHEEL,sha256=sunMa2yiYbrNLGeMVDqEA0ayyJbHlex7SCn1TZrEq60,136
24
- kinfer-0.5.3.dist-info/top_level.txt,sha256=6mY_t3PYr3Dm0dpqMk80uSnArbvGfCFkxOh1QWtgDEo,7
25
- kinfer-0.5.3.dist-info/METADATA,sha256=6802SNztiUqkdCQjF4VkSlQdyfzbRXB0CpPwNvwsPKk,1831
26
- kinfer-0.5.3.dist-info/licenses/LICENSE,sha256=Qw-Z0XTwS-diSW91e_jLeBPX9zZbAatOJTBLdPHPaC0,1069
22
+ kinfer-0.5.4.dist-info/RECORD,,
23
+ kinfer-0.5.4.dist-info/WHEEL,sha256=sunMa2yiYbrNLGeMVDqEA0ayyJbHlex7SCn1TZrEq60,136
24
+ kinfer-0.5.4.dist-info/top_level.txt,sha256=6mY_t3PYr3Dm0dpqMk80uSnArbvGfCFkxOh1QWtgDEo,7
25
+ kinfer-0.5.4.dist-info/METADATA,sha256=Da03N1PNxRcIrOj0ub_N19j9v8n0siXLjxW5ZCtsiOQ,1983
26
+ kinfer-0.5.4.dist-info/licenses/LICENSE,sha256=Qw-Z0XTwS-diSW91e_jLeBPX9zZbAatOJTBLdPHPaC0,1069
File without changes