1use super::defines::{
2 AfError, BinaryOp, ColorMap, ConvDomain, ConvMode, DType, InterpType, MatProp, MatchType,
3 RandomEngineType, SparseFormat,
4};
5use super::error::HANDLE_ERROR;
6
7use half::f16;
8use libc::{c_int, c_uint, c_void, size_t};
9use num::Complex;
10use std::convert::From;
11use std::mem;
12use std::ops::BitOr;
13
14pub type c32 = Complex<f32>;
16pub type c64 = Complex<f64>;
18pub type dim_t = libc::c_longlong;
20pub type u64_t = libc::c_ulonglong;
22pub type void_ptr = *mut libc::c_void;
24
25pub type af_array = *mut libc::c_void;
27pub type af_event = *mut libc::c_void;
29pub type af_index_t = *mut libc::c_void;
31pub type af_features = *const libc::c_void;
33pub type af_random_engine = *mut libc::c_void;
35pub type af_window = *mut libc::c_void;
37
38extern "C" {
39 fn af_get_size_of(size: *mut size_t, aftype: c_uint) -> c_int;
40 fn af_alloc_host(ptr: *mut *const c_void, bytes: dim_t) -> c_int;
41 fn af_free_host(ptr: *mut c_void) -> c_int;
42}
43
44pub fn get_size(value: DType) -> usize {
46 unsafe {
47 let mut ret_val: usize = 0;
48 let err_val = af_get_size_of(&mut ret_val as *mut size_t, value as c_uint);
49 HANDLE_ERROR(AfError::from(err_val));
50 ret_val
51 }
52}
53
54pub fn alloc_host<T>(elements: usize, _type: DType) -> *const T {
56 let ptr: *const T = ::std::ptr::null();
57 let bytes = (elements * get_size(_type)) as dim_t;
58 unsafe {
59 let err_val = af_alloc_host(&mut (ptr as *const c_void), bytes);
60 HANDLE_ERROR(AfError::from(err_val));
61 }
62 ptr
63}
64
65pub fn free_host<T>(ptr: *mut T) {
67 unsafe {
68 let err_val = af_free_host(ptr as *mut c_void);
69 HANDLE_ERROR(AfError::from(err_val));
70 }
71}
72
73impl From<i32> for AfError {
74 fn from(t: i32) -> Self {
75 assert!(AfError::SUCCESS as i32 <= t && t <= AfError::ERR_UNKNOWN as i32);
76 unsafe { mem::transmute(t) }
77 }
78}
79
80impl From<u32> for DType {
81 fn from(t: u32) -> Self {
82 assert!(DType::F32 as u32 <= t && t <= DType::U64 as u32);
83 unsafe { mem::transmute(t) }
84 }
85}
86
87impl From<u32> for InterpType {
88 fn from(t: u32) -> Self {
89 assert!(InterpType::NEAREST as u32 <= t && t <= InterpType::BICUBIC_SPLINE as u32);
90 unsafe { mem::transmute(t) }
91 }
92}
93
94impl From<u32> for ConvMode {
95 fn from(t: u32) -> Self {
96 assert!(ConvMode::DEFAULT as u32 <= t && t <= ConvMode::EXPAND as u32);
97 unsafe { mem::transmute(t) }
98 }
99}
100
101impl From<u32> for ConvDomain {
102 fn from(t: u32) -> Self {
103 assert!(ConvDomain::AUTO as u32 <= t && t <= ConvDomain::FREQUENCY as u32);
104 unsafe { mem::transmute(t) }
105 }
106}
107
108impl From<u32> for MatchType {
109 fn from(t: u32) -> Self {
110 assert!(MatchType::SAD as u32 <= t && t <= MatchType::SHD as u32);
111 unsafe { mem::transmute(t) }
112 }
113}
114
115impl From<u32> for ColorMap {
116 fn from(t: u32) -> Self {
117 assert!(ColorMap::DEFAULT as u32 <= t && t <= ColorMap::BLUE as u32);
118 unsafe { mem::transmute(t) }
119 }
120}
121
122pub trait HasAfEnum {
143 type InType: HasAfEnum;
145 type BaseType: HasAfEnum;
148 type AbsOutType: HasAfEnum;
151 type ArgOutType: HasAfEnum;
154 type UnaryOutType: HasAfEnum;
158 type ComplexOutType;
161 type MeanOutType: HasAfEnum;
165 type AggregateOutType: HasAfEnum;
176 type ProductOutType: HasAfEnum;
178 type SobelOutType: HasAfEnum;
186
187 fn get_af_dtype() -> DType;
189}
190
191impl HasAfEnum for Complex<f32> {
192 type InType = Self;
193 type BaseType = f32;
194 type AbsOutType = f32;
195 type ArgOutType = f32;
196 type UnaryOutType = Self;
197 type ComplexOutType = Self;
198 type MeanOutType = Self;
199 type AggregateOutType = Self;
200 type ProductOutType = Self;
201 type SobelOutType = Self;
202
203 fn get_af_dtype() -> DType {
204 DType::C32
205 }
206}
207impl HasAfEnum for Complex<f64> {
208 type InType = Self;
209 type BaseType = f64;
210 type AbsOutType = f64;
211 type ArgOutType = f64;
212 type UnaryOutType = Self;
213 type ComplexOutType = Self;
214 type MeanOutType = Self;
215 type AggregateOutType = Self;
216 type ProductOutType = Self;
217 type SobelOutType = Self;
218
219 fn get_af_dtype() -> DType {
220 DType::C64
221 }
222}
223impl HasAfEnum for f32 {
224 type InType = Self;
225 type BaseType = Self;
226 type AbsOutType = f32;
227 type ArgOutType = f32;
228 type UnaryOutType = Self;
229 type ComplexOutType = Complex<f32>;
230 type MeanOutType = Self;
231 type AggregateOutType = Self;
232 type ProductOutType = Self;
233 type SobelOutType = Self;
234
235 fn get_af_dtype() -> DType {
236 DType::F32
237 }
238}
239impl HasAfEnum for f64 {
240 type InType = Self;
241 type BaseType = Self;
242 type AbsOutType = f64;
243 type ArgOutType = f64;
244 type UnaryOutType = Self;
245 type ComplexOutType = Complex<f64>;
246 type MeanOutType = Self;
247 type AggregateOutType = Self;
248 type ProductOutType = Self;
249 type SobelOutType = Self;
250
251 fn get_af_dtype() -> DType {
252 DType::F64
253 }
254}
255impl HasAfEnum for bool {
256 type InType = Self;
257 type BaseType = Self;
258 type AbsOutType = f32;
259 type ArgOutType = bool;
260 type UnaryOutType = f32;
261 type ComplexOutType = Complex<f32>;
262 type MeanOutType = f32;
263 type AggregateOutType = u32;
264 type ProductOutType = bool;
265 type SobelOutType = i32;
266
267 fn get_af_dtype() -> DType {
268 DType::B8
269 }
270}
271impl HasAfEnum for u8 {
272 type InType = Self;
273 type BaseType = Self;
274 type AbsOutType = f32;
275 type ArgOutType = u8;
276 type UnaryOutType = f32;
277 type ComplexOutType = Complex<f32>;
278 type MeanOutType = f32;
279 type AggregateOutType = u32;
280 type ProductOutType = u32;
281 type SobelOutType = i32;
282
283 fn get_af_dtype() -> DType {
284 DType::U8
285 }
286}
287impl HasAfEnum for i16 {
288 type InType = Self;
289 type BaseType = Self;
290 type AbsOutType = f32;
291 type ArgOutType = i16;
292 type UnaryOutType = f32;
293 type ComplexOutType = Complex<f32>;
294 type MeanOutType = f32;
295 type AggregateOutType = i32;
296 type ProductOutType = i32;
297 type SobelOutType = i32;
298
299 fn get_af_dtype() -> DType {
300 DType::S16
301 }
302}
303impl HasAfEnum for u16 {
304 type InType = Self;
305 type BaseType = Self;
306 type AbsOutType = f32;
307 type ArgOutType = u16;
308 type UnaryOutType = f32;
309 type ComplexOutType = Complex<f32>;
310 type MeanOutType = f32;
311 type AggregateOutType = u32;
312 type ProductOutType = u32;
313 type SobelOutType = i32;
314
315 fn get_af_dtype() -> DType {
316 DType::U16
317 }
318}
319impl HasAfEnum for f16 {
320 type InType = Self;
321 type BaseType = Self;
322 type AbsOutType = Self;
323 type ArgOutType = Self;
324 type UnaryOutType = Self;
325 type ComplexOutType = Complex<f16>;
326 type MeanOutType = Self;
327 type AggregateOutType = f32;
328 type ProductOutType = f32;
329 type SobelOutType = Self;
330
331 fn get_af_dtype() -> DType {
332 DType::F16
333 }
334}
335impl HasAfEnum for i32 {
336 type InType = Self;
337 type BaseType = Self;
338 type AbsOutType = f32;
339 type ArgOutType = i32;
340 type UnaryOutType = f32;
341 type ComplexOutType = Complex<f32>;
342 type MeanOutType = f32;
343 type AggregateOutType = i32;
344 type ProductOutType = i32;
345 type SobelOutType = i32;
346
347 fn get_af_dtype() -> DType {
348 DType::S32
349 }
350}
351impl HasAfEnum for u32 {
352 type InType = Self;
353 type BaseType = Self;
354 type AbsOutType = f32;
355 type ArgOutType = u32;
356 type UnaryOutType = f32;
357 type ComplexOutType = Complex<f32>;
358 type MeanOutType = f32;
359 type AggregateOutType = u32;
360 type ProductOutType = u32;
361 type SobelOutType = i32;
362
363 fn get_af_dtype() -> DType {
364 DType::U32
365 }
366}
367impl HasAfEnum for i64 {
368 type InType = Self;
369 type BaseType = Self;
370 type AbsOutType = f64;
371 type ArgOutType = i64;
372 type UnaryOutType = f64;
373 type ComplexOutType = Complex<f64>;
374 type MeanOutType = f64;
375 type AggregateOutType = Self;
376 type ProductOutType = Self;
377 type SobelOutType = i64;
378
379 fn get_af_dtype() -> DType {
380 DType::S64
381 }
382}
383impl HasAfEnum for u64 {
384 type InType = Self;
385 type BaseType = Self;
386 type AbsOutType = f64;
387 type ArgOutType = u64;
388 type UnaryOutType = f64;
389 type ComplexOutType = Complex<f64>;
390 type MeanOutType = f64;
391 type AggregateOutType = Self;
392 type ProductOutType = Self;
393 type SobelOutType = i64;
394
395 fn get_af_dtype() -> DType {
396 DType::U64
397 }
398}
399
400impl From<u32> for SparseFormat {
401 fn from(t: u32) -> Self {
402 assert!(SparseFormat::DENSE as u32 <= t && t <= SparseFormat::COO as u32);
403 unsafe { mem::transmute(t) }
404 }
405}
406
407impl From<u32> for BinaryOp {
408 fn from(t: u32) -> Self {
409 assert!(BinaryOp::ADD as u32 <= t && t <= BinaryOp::MAX as u32);
410 unsafe { mem::transmute(t) }
411 }
412}
413
414impl From<u32> for RandomEngineType {
415 fn from(t: u32) -> Self {
416 assert!(
417 RandomEngineType::PHILOX_4X32_10 as u32 <= t
418 && t <= RandomEngineType::MERSENNE_GP11213 as u32
419 );
420 unsafe { mem::transmute(t) }
421 }
422}
423
424pub trait ImplicitPromote<RHS>: HasAfEnum {
428 type Output: HasAfEnum;
431}
432
433impl<T> ImplicitPromote<T> for T
434where
435 T: HasAfEnum,
436{
437 type Output = T;
438}
439
440macro_rules! implicit {
441 [$implType: ident, $rhsType: ident => $outType: ident] => (
442 impl ImplicitPromote< $rhsType > for $implType {
443 type Output = $outType;
444 }
445 )
446}
447
448implicit!(c64, c32 => c64);
454implicit!(c64, f64 => c64);
455implicit!(c64, f32 => c64);
456implicit!(c64, i64 => c64);
457implicit!(c64, u64 => c64);
458implicit!(c64, i32 => c64);
459implicit!(c64, u32 => c64);
460implicit!(c64, i16 => c64);
461implicit!(c64, u16 => c64);
462implicit!(c64, bool => c64);
463implicit!(c64, u8 => c64);
464
465implicit!(c32, c64 => c64);
467implicit!(c32, f64 => c64);
468implicit!(c32, f32 => c32);
469implicit!(c32, i64 => c32);
470implicit!(c32, u64 => c32);
471implicit!(c32, i32 => c32);
472implicit!(c32, u32 => c32);
473implicit!(c32, i16 => c32);
474implicit!(c32, u16 => c32);
475implicit!(c32, bool => c32);
476implicit!(c32, u8 => c32);
477
478implicit!(f64, c64 => c64);
480implicit!(f64, c32 => c64);
481implicit!(f64, f32 => f64);
482implicit!(f64, i64 => f64);
483implicit!(f64, u64 => f64);
484implicit!(f64, i32 => f64);
485implicit!(f64, u32 => f64);
486implicit!(f64, i16 => f64);
487implicit!(f64, u16 => f64);
488implicit!(f64, bool => f64);
489implicit!(f64, u8 => f64);
490
491implicit!(f32, c64 => c64);
493implicit!(f32, c32 => c32);
494implicit!(f32, f64 => f64);
495implicit!(f32, i64 => f32);
496implicit!(f32, u64 => f32);
497implicit!(f32, i32 => f32);
498implicit!(f32, u32 => f32);
499implicit!(f32, i16 => f32);
500implicit!(f32, u16 => f32);
501implicit!(f32, bool => f32);
502implicit!(f32, u8 => f32);
503
504implicit!(i64, c64 => c64);
506implicit!(i64, c32 => c32);
507implicit!(i64, f64 => f64);
508implicit!(i64, f32 => f32);
509implicit!(i64, u64 => u64);
510implicit!(i64, i32 => i64);
511implicit!(i64, u32 => i64);
512implicit!(i64, i16 => i64);
513implicit!(i64, u16 => i64);
514implicit!(i64, bool => i64);
515implicit!(i64, u8 => i64);
516
517implicit!(u64, c64 => c64);
519implicit!(u64, c32 => c32);
520implicit!(u64, f64 => f64);
521implicit!(u64, f32 => f32);
522implicit!(u64, i64 => u64);
523implicit!(u64, i32 => u64);
524implicit!(u64, u32 => u64);
525implicit!(u64, i16 => u64);
526implicit!(u64, u16 => u64);
527implicit!(u64, bool => u64);
528implicit!(u64, u8 => u64);
529
530implicit!(i32, c64 => c64);
532implicit!(i32, c32 => c32);
533implicit!(i32, f64 => f64);
534implicit!(i32, f32 => f32);
535implicit!(i32, i64 => i64);
536implicit!(i32, u64 => u64);
537implicit!(i32, u32 => u32);
538implicit!(i32, i16 => i32);
539implicit!(i32, u16 => i32);
540implicit!(i32, bool => i32);
541implicit!(i32, u8 => i32);
542
543implicit!(u32, c64 => c64);
545implicit!(u32, c32 => c32);
546implicit!(u32, f64 => f64);
547implicit!(u32, f32 => f32);
548implicit!(u32, i64 => i64);
549implicit!(u32, u64 => u64);
550implicit!(u32, i32 => u32);
551implicit!(u32, i16 => u32);
552implicit!(u32, u16 => u32);
553implicit!(u32, bool => u32);
554implicit!(u32, u8 => u32);
555
556implicit!(i16, c64 => c64);
558implicit!(i16, c32 => c32);
559implicit!(i16, f64 => f64);
560implicit!(i16, f32 => f32);
561implicit!(i16, i64 => i64);
562implicit!(i16, u64 => u64);
563implicit!(i16, i32 => i32);
564implicit!(i16, u32 => u32);
565implicit!(i16, u16 => u16);
566implicit!(i16, bool => u16);
567implicit!(i16, u8 => u16);
568
569implicit!(u16, c64 => c64);
571implicit!(u16, c32 => c32);
572implicit!(u16, f64 => f64);
573implicit!(u16, f32 => f32);
574implicit!(u16, i64 => i64);
575implicit!(u16, u64 => u64);
576implicit!(u16, i32 => i32);
577implicit!(u16, u32 => u32);
578implicit!(u16, i16 => u16);
579implicit!(u16, bool => u16);
580implicit!(u16, u8 => u16);
581
582implicit!(u8, c64 => c64);
584implicit!(u8, c32 => c32);
585implicit!(u8, f64 => f64);
586implicit!(u8, f32 => f32);
587implicit!(u8, i64 => i64);
588implicit!(u8, u64 => u64);
589implicit!(u8, i32 => i32);
590implicit!(u8, u32 => u32);
591implicit!(u8, i16 => i16);
592implicit!(u8, u16 => u16);
593implicit!(u8, bool => u8);
594
595implicit!(bool, c64 => c64);
597implicit!(bool, c32 => c32);
598implicit!(bool, f64 => f64);
599implicit!(bool, f32 => f32);
600implicit!(bool, i64 => i64);
601implicit!(bool, u64 => u64);
602implicit!(bool, i32 => i32);
603implicit!(bool, u32 => u32);
604implicit!(bool, i16 => i16);
605implicit!(bool, u16 => u16);
606implicit!(bool, u8 => u8);
607
608pub trait FloatingPoint: HasAfEnum {
610 fn is_real() -> bool {
612 false
613 }
614 fn is_complex() -> bool {
616 false
617 }
618}
619
620impl FloatingPoint for Complex<f64> {
621 fn is_complex() -> bool {
622 true
623 }
624}
625impl FloatingPoint for Complex<f32> {
626 fn is_complex() -> bool {
627 true
628 }
629}
630impl FloatingPoint for f64 {
631 fn is_real() -> bool {
632 true
633 }
634}
635impl FloatingPoint for f32 {
636 fn is_real() -> bool {
637 true
638 }
639}
640
641pub trait RealFloating: HasAfEnum {}
643
644impl RealFloating for f64 {}
645impl RealFloating for f32 {}
646
647pub trait ComplexFloating: HasAfEnum {}
649
650impl ComplexFloating for c64 {}
651impl ComplexFloating for c32 {}
652
653pub trait RealNumber: HasAfEnum {}
655
656impl RealNumber for f64 {}
657impl RealNumber for f32 {}
658impl RealNumber for i32 {}
659impl RealNumber for u32 {}
660impl RealNumber for i16 {}
661impl RealNumber for u16 {}
662impl RealNumber for u8 {}
663impl RealNumber for bool {}
664impl RealNumber for u64 {}
665impl RealNumber for i64 {}
666
667pub trait Scanable: HasAfEnum {}
669
670impl Scanable for i32 {}
671impl Scanable for u32 {}
672impl Scanable for u64 {}
673impl Scanable for i64 {}
674
675pub trait ImageNativeType: HasAfEnum {}
678
679impl ImageNativeType for f32 {}
680impl ImageNativeType for u16 {}
681impl ImageNativeType for u8 {}
682
683pub trait ImageFilterType: HasAfEnum {}
686
687impl ImageFilterType for f64 {}
688impl ImageFilterType for f32 {}
689impl ImageFilterType for i32 {}
690impl ImageFilterType for u32 {}
691impl ImageFilterType for i16 {}
692impl ImageFilterType for u16 {}
693impl ImageFilterType for u8 {}
694impl ImageFilterType for bool {}
695
696pub trait GrayRGBConvertible: HasAfEnum {}
700
701impl GrayRGBConvertible for f64 {}
702impl GrayRGBConvertible for f32 {}
703impl GrayRGBConvertible for i32 {}
704impl GrayRGBConvertible for u32 {}
705impl GrayRGBConvertible for i16 {}
706impl GrayRGBConvertible for u16 {}
707impl GrayRGBConvertible for u8 {}
708
709pub trait MomentsComputable: HasAfEnum {}
712
713impl MomentsComputable for f64 {}
714impl MomentsComputable for f32 {}
715impl MomentsComputable for i32 {}
716impl MomentsComputable for u32 {}
717impl MomentsComputable for i16 {}
718impl MomentsComputable for u16 {}
719impl MomentsComputable for u8 {}
720
721pub trait MedianComputable: HasAfEnum {}
724
725impl MedianComputable for f64 {}
726impl MedianComputable for f32 {}
727impl MedianComputable for i32 {}
728impl MedianComputable for u32 {}
729impl MedianComputable for i16 {}
730impl MedianComputable for u16 {}
731impl MedianComputable for u8 {}
732
733pub trait EdgeComputable: HasAfEnum {}
737
738impl EdgeComputable for f64 {}
739impl EdgeComputable for f32 {}
740impl EdgeComputable for i32 {}
741impl EdgeComputable for u32 {}
742impl EdgeComputable for i16 {}
743impl EdgeComputable for u16 {}
744impl EdgeComputable for u8 {}
745
746pub trait CovarianceComputable: HasAfEnum {}
748
749impl CovarianceComputable for f64 {}
750impl CovarianceComputable for f32 {}
751impl CovarianceComputable for i32 {}
752impl CovarianceComputable for u32 {}
753impl CovarianceComputable for i16 {}
754impl CovarianceComputable for u16 {}
755impl CovarianceComputable for u8 {}
756impl CovarianceComputable for u64 {}
757impl CovarianceComputable for i64 {}
758
759pub trait ConfidenceCCInput: HasAfEnum {}
761
762impl ConfidenceCCInput for f32 {}
763impl ConfidenceCCInput for u32 {}
764impl ConfidenceCCInput for u16 {}
765impl ConfidenceCCInput for u8 {}
766
767pub trait DeconvInput: HasAfEnum {}
769
770impl DeconvInput for f32 {}
771impl DeconvInput for i16 {}
772impl DeconvInput for u16 {}
773impl DeconvInput for u8 {}
774
775pub trait ReduceByKeyInput: HasAfEnum {}
777
778impl ReduceByKeyInput for i32 {}
779impl ReduceByKeyInput for u32 {}
780
781impl From<u32> for MatProp {
782 fn from(t: u32) -> Self {
783 unsafe { mem::transmute(t) }
784 }
785}
786
787impl BitOr for MatProp {
788 type Output = Self;
789
790 fn bitor(self, rhs: Self) -> Self {
791 Self::from(self as u32 | rhs as u32)
792 }
793}
794
795pub trait Fromf64 {
799 fn fromf64(value: f64) -> Self;
801}
802
803#[rustfmt::skip]
804impl Fromf64 for usize{ fn fromf64(value: f64) -> Self { value as Self }}
805#[rustfmt::skip]
806impl Fromf64 for f64 { fn fromf64(value: f64) -> Self { value as Self }}
807#[rustfmt::skip]
808impl Fromf64 for u64 { fn fromf64(value: f64) -> Self { value as Self }}
809#[rustfmt::skip]
810impl Fromf64 for i64 { fn fromf64(value: f64) -> Self { value as Self }}
811#[rustfmt::skip]
812impl Fromf64 for f32 { fn fromf64(value: f64) -> Self { value as Self }}
813#[rustfmt::skip]
814impl Fromf64 for u32 { fn fromf64(value: f64) -> Self { value as Self }}
815#[rustfmt::skip]
816impl Fromf64 for i32 { fn fromf64(value: f64) -> Self { value as Self }}
817#[rustfmt::skip]
818impl Fromf64 for u16 { fn fromf64(value: f64) -> Self { value as Self }}
819#[rustfmt::skip]
820impl Fromf64 for i16 { fn fromf64(value: f64) -> Self { value as Self }}
821#[rustfmt::skip]
822impl Fromf64 for u8 { fn fromf64(value: f64) -> Self { value as Self }}
823#[rustfmt::skip]
824impl Fromf64 for bool { fn fromf64(value: f64) -> Self { value > 0.0 }}
825
826pub trait IndexableType: HasAfEnum {}
828
829impl IndexableType for f64 {}
830impl IndexableType for i64 {}
831impl IndexableType for u64 {}
832impl IndexableType for f32 {}
833impl IndexableType for i32 {}
834impl IndexableType for u32 {}
835impl IndexableType for i16 {}
836impl IndexableType for u16 {}
837impl IndexableType for u8 {}
838
839pub trait IntegralType {}
841
842impl IntegralType for i64 {}
843impl IntegralType for u64 {}
844impl IntegralType for i32 {}
845impl IntegralType for u32 {}
846impl IntegralType for i16 {}
847impl IntegralType for u16 {}
848impl IntegralType for u8 {}
849impl IntegralType for bool {}