#bindings #github #zfp #com-llnl-zfp #cuda #linker

sys zfp-sys

对ZFP的原始Rust绑定(https://github.com/LLNL/zfp)

16个版本

0.1.15 2024年3月6日
0.1.14 2023年12月17日
0.1.13 2023年6月15日
0.1.11 2022年7月19日
0.1.4 2019年2月20日

压缩类别中排名第168

Download history 20/week @ 2024-04-08 60/week @ 2024-04-15 42/week @ 2024-04-22 140/week @ 2024-04-29 16/week @ 2024-05-06 38/week @ 2024-05-13 26/week @ 2024-05-20 48/week @ 2024-05-27 42/week @ 2024-06-03 166/week @ 2024-06-10 74/week @ 2024-06-17 90/week @ 2024-06-24 88/week @ 2024-07-01 26/week @ 2024-07-08 116/week @ 2024-07-15 86/week @ 2024-07-22

每月下载量318
用于 2 crates

MIT许可协议

1.5MB
32K SLoC

C 16K SLoC // 0.1% comments C++ 12K SLoC // 0.1% comments Bitbake 1.5K SLoC FORTRAN Modern 1K SLoC Cython 869 SLoC // 0.0% comments CUDA 396 SLoC // 0.0% comments Python 255 SLoC // 0.3% comments Rust 118 SLoC // 0.2% comments FORTRAN Legacy 83 SLoC Shell 79 SLoC // 0.2% comments Batch 27 SLoC

zfp-sys

对ZFP的原始Rust绑定(https://github.com/LLNL/zfp)。

ZFP版本1.0.0+

从版本0.1.13开始,不再支持旧版本的zfp。

CUDA支持

启用cuda功能,通过链接CUDA库来启用GPU卸载。有关如何在实践中使用此功能的更多信息,请参阅https://zfp.readthedocs.io/en/release0.5.5/execution.html

静态链接

static功能添加到crate依赖项中,以静态链接zfp库。这也从库中移除了OpenMP支持,以消除对动态链接的OpenMP库的依赖。

示例

use zfp_sys::*;

fn compress_array() {
        //based on examples/simple.c
        let nx = 100;
        let ny = 100;
        let nz = 100;

        let mut array: Vec<f64> = vec![0.0; nx * ny * nz];

        for i in 0..nx {
            for j in 0..ny {
                for k in 0..nz {
                    let x = 2.0 * (i as f64) / (nx as f64);
                    let y = 2.0 * (j as f64) / (ny as f64);
                    let z = 2.0 * (k as f64) / (nz as f64);
                    array[i + nx * (j + ny * k)] = (-(x * x + y * y + z * z)).exp();
                }
            }
        }

        println!("original data sample: {:?}", &array[0..nx]);

        //compression
        /* allocate meta data for the 3D array a[nz][ny][nx] */
        let data_type = zfp_type_zfp_type_double;
        let field = unsafe {
            zfp_field_3d(
                array.as_mut_ptr() as *mut std::ffi::c_void,
                data_type,
                nx as usize,
                ny as usize,
                nz as usize,
            )
        };

        /* allocate meta data for a compressed stream */
        let zfp = unsafe { zfp_stream_open(std::ptr::null_mut() as *mut bitstream) };

        /* set compression mode and parameters via one of three functions */
        unsafe { zfp_stream_set_rate(zfp, 8.0, data_type, 3, 0) };
        /*  zfp_stream_set_precision(zfp, precision); */
        //let tolerance = 1.0e-3;
        //unsafe { zfp_stream_set_accuracy(zfp, tolerance) };

        #[cfg(feature = "cuda")]
        {
            let ret = unsafe { zfp_stream_set_execution(zfp, zfp_exec_policy_zfp_exec_cuda) };

            if ret == 0 {
                println!("failed to set the execution policy to zfp_exec_cuda");
                assert!(false);
            }
        }

        /* allocate buffer for compressed data */
        let bufsize = unsafe { zfp_stream_maximum_size(zfp, field) };
        let mut buffer: Vec<u8> = vec![0; bufsize as usize];

        /* associate bit stream with allocated buffer */
        let stream = unsafe { stream_open(buffer.as_mut_ptr() as *mut std::ffi::c_void, bufsize) };
        unsafe {
            zfp_stream_set_bit_stream(zfp, stream);
            zfp_stream_rewind(zfp);
        }

        /* compress array and output compressed stream */
        let zfpsize = unsafe { zfp_compress(zfp, field) };
        if zfpsize == 0 {
            println!("compression failed");
            assert!(false);
        } else {
            let original_size = nx * ny * nz * std::mem::size_of::<f64>();
            let ratio = (original_size as f64) / (zfpsize as f64);

            println!(
                "bufsize: {} bytes, original size: {} bytes, compressed size: {} bytes, ratio: {}",
                bufsize, original_size, zfpsize, ratio
            );
        }

        /* rewind compressed stream and decompress array */
        unsafe { zfp_stream_rewind(zfp) };
        let ret = unsafe { zfp_decompress(zfp, field) };
        if ret == 0 {
            println!("decompression failed");
            assert!(false);
        } else {
            println!("ret: {}", ret);
        }

        println!("decompressed data sample: {:?}", &array[0..nx]);

        /* clean up */
        unsafe {
            zfp_field_free(field);
            zfp_stream_close(zfp);
            stream_close(stream);
        }

        assert!(true);
    }

无运行时依赖

~0–2MB
~40K SLoC