(#18958) fpzip: add recipe

* fpzip: add recipe

* add FPZIP_SHARED_LIBS
This commit is contained in:
toge
2023-08-11 00:29:28 +09:00
committed by GitHub
parent 216654c1ae
commit f3a66013c2
6 changed files with 262 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
sources:
"1.3.0":
url: "https://github.com/LLNL/fpzip/releases/download/1.3.0/fpzip-1.3.0.tar.gz"
sha256: "248df7d84259e3feaa4c4797956b2a77c3fcd734e8f8fdc51ce171dcf4f0136c"

View File

@@ -0,0 +1,80 @@
from conan import ConanFile
from conan.tools.files import apply_conandata_patches, export_conandata_patches, get, copy, rmdir
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
import os
required_conan_version = ">=1.53.0"
class FpzipConan(ConanFile):
name = "fpzip"
description = "Lossless compressor of multidimensional floating-point arrays"
license = "BSD-3-Clause"
url = "https://github.com/conan-io/conan-center-index"
homepage = "http://fpzip.llnl.gov/"
topics = ("compression", "lossless", "floating-point")
package_type = "library"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
"with_fp": ["fast", "safe", "emul", "int"],
}
default_options = {
"shared": False,
"fPIC": True,
"with_fp": "fast",
}
def export_sources(self):
export_conandata_patches(self)
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")
def layout(self):
cmake_layout(self, src_folder="src")
def source(self):
get(self, **self.conan_data["sources"][self.version], strip_root=True)
@property
def _fp_name_table(self):
return {
"fast": "FPZIP_FP_FAST",
"safe": "FPZIP_FP_SAFE",
"emul": "FPZIP_FP_EMUL",
"int": "FPZIP_FP_INT",
}
def generate(self):
tc = CMakeToolchain(self)
tc.variables["FPZIP_FP"] = self._fp_name_table.get(str(self.options.with_fp), "FP_ZIP_FAST")
tc.generate()
deps = CMakeDeps(self)
deps.generate()
def build(self):
apply_conandata_patches(self)
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
copy(self, pattern="LICENSE", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
cmake = CMake(self)
cmake.install()
rmdir(self, os.path.join(self.package_folder, "lib", "cmake"))
def package_info(self):
self.cpp_info.libs = ["fpzip"]
self.cpp_info.defines.append("FPZIP_FP={}".format(self._fp_name_table.get(str(self.options.with_fp), "FP_ZIP_FAST")))
if self.options.shared:
self.cpp_info.defines.append("FPZIP_SHARED_LIBS")
if self.settings.compiler in ["gcc", "clang", "apple-clang"]:
self.cpp_info.system_libs += ["stdc++"]

View File

@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.15)
project(test_package LANGUAGES C)
find_package(fpzip REQUIRED CONFIG)
add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} PRIVATE fpzip::fpzip)

View File

@@ -0,0 +1,26 @@
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import cmake_layout, CMake
import os
class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv"
test_type = "explicit"
def requirements(self):
self.requires(self.tested_reference_str)
def layout(self):
cmake_layout(self)
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def test(self):
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindir, "test_package")
self.run(bin_path, env="conanrun")

View File

@@ -0,0 +1,142 @@
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fpzip.h"
static size_t
compress(FPZ* fpz, const void* data)
{
size_t size;
/* write header */
if (!fpzip_write_header(fpz)) {
fprintf(stderr, "cannot write header: %s\n", fpzip_errstr[fpzip_errno]);
return 0;
}
/* perform actual compression */
size = fpzip_write(fpz, data);
if (!size) {
fprintf(stderr, "compression failed: %s\n", fpzip_errstr[fpzip_errno]);
return 0;
}
return size;
}
static int
decompress(FPZ* fpz, void* data, size_t inbytes)
{
/* read header */
if (!fpzip_read_header(fpz)) {
fprintf(stderr, "cannot read header: %s\n", fpzip_errstr[fpzip_errno]);
return 0;
}
/* make sure array size stored in header matches expectations */
if ((fpz->type == FPZIP_TYPE_FLOAT ? sizeof(float) : sizeof(double)) * fpz->nx * fpz->ny * fpz->nz * fpz->nf != inbytes) {
fprintf(stderr, "array size does not match dimensions from header\n");
return 0;
}
/* perform actual decompression */
if (!fpzip_read(fpz, data)) {
fprintf(stderr, "decompression failed: %s\n", fpzip_errstr[fpzip_errno]);
return 0;
}
return 1;
}
static float
float_rand()
{
static unsigned int seed = 1;
double val;
seed = 1103515245 * seed + 12345;
seed &= 0x7fffffffu;
val = ldexp((double)seed, -31);
val = 2 * val - 1;
val *= val * val;
val *= val * val;
return val;
}
/* generate a trilinear field perturbed by random noise */
float*
float_field(int nx, int ny, int nz, float offset)
{
int n = nx * ny * nz;
float* field = malloc(n * sizeof(float));
int i, x, y, z;
/* generate random field */
*field = offset;
for (i = 1; i < n; i++)
field[i] = float_rand();
/* integrate along x */
for (z = 0; z < nz; z++)
for (y = 0; y < ny; y++)
for (x = 1; x < nx; x++)
field[x + nx * (y + ny * z)] += field[(x - 1) + nx * (y + ny * z)];
/* integrate along y */
for (z = 0; z < nz; z++)
for (y = 1; y < ny; y++)
for (x = 0; x < nx; x++)
field[x + nx * (y + ny * z)] += field[x + nx * ((y - 1) + ny * z)];
/* integrate along z */
for (z = 1; z < nz; z++)
for (y = 0; y < ny; y++)
for (x = 0; x < nx; x++)
field[x + nx * (y + ny * z)] += field[x + nx * (y + ny * (z - 1))];
return field;
}
static void
test_float_array(const float* field, int nx, int ny, int nz, int prec)
{
int status;
unsigned int actual_checksum;
int dims = (nz == 1 ? ny == 1 ? 1 : 2 : 3);
size_t inbytes = nx * ny * nz * sizeof(float);
size_t bufbytes = 1024 + inbytes;
size_t outbytes = 0;
void* buffer = malloc(bufbytes);
float* copy = malloc(inbytes);
char name[0x100];
/* compress to memory */
FPZ* fpz = fpzip_write_to_buffer(buffer, bufbytes);
fpz->type = FPZIP_TYPE_FLOAT;
fpz->prec = prec;
fpz->nx = nx;
fpz->ny = ny;
fpz->nz = nz;
fpz->nf = 1;
outbytes = compress(fpz, field);
status = (0 < outbytes && outbytes <= bufbytes);
fpzip_write_close(fpz);
sprintf(name, "test.float.%dd.prec%d.compress", dims, prec);
/* decompress */
fpz = fpzip_read_from_buffer(buffer);
status = decompress(fpz, copy, inbytes);
fpzip_read_close(fpz);
sprintf(name, "test.float.%dd.prec%d.decompress", dims, prec);
free(copy);
free(buffer);
}
static int
test_float(int nx, int ny, int nz)
{
float* field = float_field(nx, ny, nz, 0);
int prec = 8;
test_float_array(field, nx * ny * nz, 1, 1, prec);
test_float_array(field, nx, ny * nz, 1, prec);
test_float_array(field, nx, ny, nz, prec);
free(field);
}
int main(void) {
test_float(65, 64, 63);
return 0;
}

3
recipes/fpzip/config.yml Normal file
View File

@@ -0,0 +1,3 @@
versions:
"1.3.0":
folder: all