diff --git a/recipes/blasfeo/all/conandata.yml b/recipes/blasfeo/all/conandata.yml new file mode 100644 index 0000000000000..7cb64878da798 --- /dev/null +++ b/recipes/blasfeo/all/conandata.yml @@ -0,0 +1,8 @@ +sources: + # Newer versions at the top + "0.1.3": + url: "https://github.com/giaf/blasfeo/archive/refs/tags/0.1.3.tar.gz" + sha256: "c33eb6467a90d6075a8db34e5ab239ecdda38c5261ae096def122fe7a0f98780" + "0.1.2": + url: "https://github.com/giaf/blasfeo/archive/refs/tags/0.1.2.tar.gz" + sha256: "079c9c90db1249aac59fa649c42667d46f4d458049e5986762035388f22fc005" diff --git a/recipes/blasfeo/all/conanfile.py b/recipes/blasfeo/all/conanfile.py new file mode 100644 index 0000000000000..95d10ce179f8c --- /dev/null +++ b/recipes/blasfeo/all/conanfile.py @@ -0,0 +1,174 @@ +import os + +from conan import ConanFile +from conan.errors import ConanInvalidConfiguration +from conan.tools.apple import is_apple_os +from conan.tools.files import ( + apply_conandata_patches, + copy, + export_conandata_patches, + get, +) +from conan.tools.gnu import Autotools, AutotoolsToolchain + +required_conan_version = ">=1.57.0" + + +class BlasfeoConan(ConanFile): + name = "blasfeo" + description = "Basic linear algebra subroutines for embedded optimization." + topics = ( + "blasfeo", + "blas", + "linear-algebra", + "matrices", + "embedded", + "optimization", + ) + license = "BSD-2-Clause" + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://github.com/giaf/blasfeo" + settings = "os", "arch", "compiler", "build_type" + + _blasfeo_arch_targets = { + "x86_64": [ + "X64_INTEL_SKYLAKE_X", + "X64_INTEL_HASWELL", + "X64_INTEL_SANDY_BRIDGE", + "X64_INTEL_CORE", + "X64_AMD_BULLDOZER", + ], + "x86": [ + "X86_AMD_JAGUAR", + "X86_AMD_BARCELONA", + ], + "armv7": [ + "ARMV7A_ARM_CORTEX_A15", + "ARMV7A_ARM_CORTEX_A9", + "ARMV7A_ARM_CORTEX_A7", + ], + "armv8": [ + "ARMV8A_APPLE_M1", + "ARMV8A_ARM_CORTEX_A76", + "ARMV8A_ARM_CORTEX_A73", + "ARMV8A_ARM_CORTEX_A57", + "ARMV8A_ARM_CORTEX_A55", + "ARMV8A_ARM_CORTEX_A53", + ], + "generic": ["GENERIC"], + } + + options = { + "fPIC": [True, False], + "shared": [True, False], + "target": [x for list in [i for i in _blasfeo_arch_targets.values()] for x in list], + "la": [ + "HIGH_PERFORMANCE", + "REFERENCE", + "EXTERNAL_BLAS_WRAPPER", + ], + "mf": [ + "COLMAJ", + "PANELMAJ", + ], + } + default_options = { + "fPIC": False, + "shared": False, + "target": "GENERIC", + "la": "HIGH_PERFORMANCE", + "mf": "PANELMAJ", + } + + def export_sources(self): + export_conandata_patches(self) + + def generate(self): + toolchain = AutotoolsToolchain(self) + toolchain.generate() + + 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") + self.settings.rm_safe("compiler.libcxx") + self.settings.rm_safe("compiler.cppstd") + + def validate(self): + blasfeo_target = str(self.options.target) + if blasfeo_target != self._blasfeo_arch_targets["generic"][0]: + if blasfeo_target not in self._blasfeo_arch_targets[str(self.settings.arch)]: + raise ConanInvalidConfiguration( + "Invalid arch: {} and target: {} combination.".format(self.settings.arch, self.options.target) + ) + if self.settings.os == "Windows": + # Installation instructions do not contain Windows information. + # There is also an open issue for Windows support: https://github.com/giaf/blasfeo/issues/101 + raise ConanInvalidConfiguration( + "This recipe does not support {} builds of {}.".format(self.settings.os, self.name) + ) + if self.options.shared and is_apple_os(self): + raise ConanInvalidConfiguration( + "{} does not support shared builds for {}.".format(self.name, self.settings.os) + ) + + def requirements(self): + self.requires(self.tested_reference_str) + + def source(self): + get(self, **self.conan_data["sources"][self.version], strip_root=True) + + def build(self): + apply_conandata_patches(self) + + target = "shared_library" if self.options.shared else "static_library" + args = [ + "TARGET={}".format(self.options.target), + "LA={}".format(self.options.la), + "MF={}".format(self.options.mf), + ] + autotools = Autotools(self) + autotools.make(target=target, args=args) + + def package(self): + copy( + self, + pattern="LICENSE*", + src=self.source_folder, + dst=os.path.join(self.package_folder, "licenses"), + keep_path=False, + ) + copy( + self, + pattern="*.h*", + src=os.path.join(self.source_folder, "include"), + dst=os.path.join(self.package_folder, "include"), + keep_path=False, + ) + copy( + self, + pattern="*.a", + src=os.path.join(self.source_folder, "lib"), + dst=os.path.join(self.package_folder, "lib"), + keep_path=False, + ) + copy( + self, + pattern="*.so", + src=os.path.join(self.source_folder, "lib"), + dst=os.path.join(self.package_folder, "lib"), + keep_path=False, + ) + + def package_info(self): + self.cpp_info.set_property("cmake_find_mode", "both") + self.cpp_info.set_property("cmake_file_name", "BLASFEO") + self.cpp_info.set_property("cmake_target_name", "BLASFEO::BLASFEO") + self.cpp_info.set_property("pkg_config_name", "blasfeo") + self.cpp_info.names["cmake_find_package"] = "BLASFEO" + self.cpp_info.names["cmake_find_package_multi"] = "BLASFEO" + self.cpp_info.libs = ["blasfeo"] + self.cpp_info.system_libs = ["m"] diff --git a/recipes/blasfeo/all/test_package/CMakeLists.txt b/recipes/blasfeo/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..9c07ba46eca21 --- /dev/null +++ b/recipes/blasfeo/all/test_package/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.1) +project(test_package LANGUAGES C) + +find_package(BLASFEO REQUIRED CONFIG) + +add_executable(${PROJECT_NAME} test_package.c) + +target_link_libraries(${PROJECT_NAME} PRIVATE BLASFEO::BLASFEO) diff --git a/recipes/blasfeo/all/test_package/conanfile.py b/recipes/blasfeo/all/test_package/conanfile.py new file mode 100644 index 0000000000000..fb08dd081e1f6 --- /dev/null +++ b/recipes/blasfeo/all/test_package/conanfile.py @@ -0,0 +1,27 @@ +import os +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import cmake_layout, CMake + + +# It will become the standard on Conan 2.x +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv" + test_type = "explicit" + + def layout(self): + cmake_layout(self) + + def requirements(self): + self.requires(self.tested_reference_str) + + 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.bindirs[0], "test_package") + self.run(bin_path, env="conanrun") diff --git a/recipes/blasfeo/all/test_package/test_package.c b/recipes/blasfeo/all/test_package/test_package.c new file mode 100644 index 0000000000000..eb81cf8a8f245 --- /dev/null +++ b/recipes/blasfeo/all/test_package/test_package.c @@ -0,0 +1,83 @@ +// Modified blasfeo/examples/getting_started.c example + +#include +#include + +#include + +int main() +{ + printf("Testing processor\n"); + + char supportString[50]; + blasfeo_processor_library_string(supportString); + printf("Library requires processor features:%s\n", supportString); + + int features = 0; + if (!blasfeo_processor_cpu_features(&features)) + { + printf("Current processor does not support the current compiled BLASFEO library.\n"); + printf("Please get a BLASFEO library compatible with this processor.\n"); + return 3; + } + blasfeo_processor_feature_string(features, supportString); + printf("Processor supports features:%s\n", supportString); + + /* + NOTE: Code above will compile and run without output even if library not linked properly or if not native target. + Code below which does actual matrix calculations requires linked -lm (math.h) and will not compile otherwise. + */ + + int n = 4; // matrix size + + // A + struct blasfeo_dmat sA; // matrix structure + blasfeo_allocate_dmat(n, n, &sA); // allocate and assign memory needed by A + + // B + struct blasfeo_dmat sB; // matrix structure + int B_size = blasfeo_memsize_dmat(n, n); // size of memory needed by B + void *B_mem_align; + v_zeros_align(&B_mem_align, B_size); // allocate memory needed by B + blasfeo_create_dmat(n, n, &sB, B_mem_align); // assign aligned memory to struct + + // C + struct blasfeo_dmat sC; // matrix structure + int C_size = blasfeo_memsize_dmat(n, n); // size of memory needed by C + C_size += 64; // 64-bytes alignment + void *C_mem = malloc(C_size); + void *C_mem_align = (void *)((((unsigned long long)C_mem) + 63) / 64 * 64); // align memory pointer + blasfeo_create_dmat(n, n, &sC, C_mem_align); // assign aligned memory to struct + + int ii; // loop index + + // A + double *A = malloc(n * n * sizeof(double)); + for (ii = 0; ii < n * n; ii++) + { + A[ii] = ii; + } + int lda = n; + blasfeo_pack_dmat(n, n, A, lda, &sA, 0, 0); // convert from column-major to BLASFEO dmat + free(A); + + // B + blasfeo_dgese(n, n, 0.0, &sB, 0, 0); // set B to zero + for (ii = 0; ii < n; ii++) + { + BLASFEO_DMATEL(&sB, ii, ii) = 1.0; // set B diagonal to 1.0 accessing dmat elements + } + + // C + blasfeo_dgese(n, n, -1.0, &sC, 0, 0); // set C to -1.0 + blasfeo_dgemm_nt(n, n, n, 1.0, &sA, 0, 0, &sB, 0, 0, 0.0, &sC, 0, 0, &sC, 0, 0); + + printf("\nC = \n"); + blasfeo_print_dmat(n, n, &sC, 0, 0); + + blasfeo_free_dmat(&sA); + v_free_align(B_mem_align); + free(C_mem); + + return 0; +} diff --git a/recipes/blasfeo/all/test_v1_package/CMakeLists.txt b/recipes/blasfeo/all/test_v1_package/CMakeLists.txt new file mode 100644 index 0000000000000..be46993f6f685 --- /dev/null +++ b/recipes/blasfeo/all/test_v1_package/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.1) +project(test_package LANGUAGES C) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) + +find_package(BLASFEO REQUIRED CONFIG) + +add_executable(${PROJECT_NAME} ../test_package/test_package.c) +target_link_libraries(${PROJECT_NAME} PRIVATE BLASFEO::BLASFEO) diff --git a/recipes/blasfeo/all/test_v1_package/conanfile.py b/recipes/blasfeo/all/test_v1_package/conanfile.py new file mode 100644 index 0000000000000..c492184eec19c --- /dev/null +++ b/recipes/blasfeo/all/test_v1_package/conanfile.py @@ -0,0 +1,19 @@ +from conans import ConanFile, CMake +from conan.tools.build import cross_building +import os + + +# legacy validation with Conan 1.x +class TestPackageV1Conan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "cmake", "cmake_find_package_multi" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if not cross_building(self): + bin_path = os.path.join("bin", "test_package") + self.run(bin_path, run_environment=True) diff --git a/recipes/blasfeo/config.yml b/recipes/blasfeo/config.yml new file mode 100644 index 0000000000000..94a980932c48e --- /dev/null +++ b/recipes/blasfeo/config.yml @@ -0,0 +1,6 @@ +versions: + # Newer versions at the top + "0.1.3": + folder: all + "0.1.2": + folder: all