From 8f4e49296fc3b6026e2fb0ff25f09b2065e583cf Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Sat, 28 Feb 2026 23:31:58 -0800 Subject: [PATCH 01/22] move mkl_umath build system to meson * removes cmake and setup.py from the project * vendors process_src_template.py from numpy and updates vendored conv_template.py * updates build scripts * updates meta.yaml * updates pyproject.toml * adds meson.build and meson.options --- CMakeLists.txt | 147 ----------------------- _vendored/README.md | 4 +- _vendored/conv_template.py | 58 +++++---- _vendored/process_src_template.py | 66 ++++++++++ conda-recipe-cf/build.sh | 36 +++--- conda-recipe-cf/meta.yaml | 6 +- conda-recipe/build.sh | 36 +++--- conda-recipe/meta.yaml | 6 +- meson.build | 172 +++++++++++++++++++++++++++ meson.options | 2 + mkl_umath/generate_umath.py | 2 +- mkl_umath/ufunc_docstrings_numpy1.py | 4 +- pyproject.toml | 13 +- setup.py | 107 ----------------- 14 files changed, 328 insertions(+), 331 deletions(-) delete mode 100644 CMakeLists.txt create mode 100644 _vendored/process_src_template.py create mode 100644 meson.build create mode 100644 meson.options delete mode 100644 setup.py diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 4a00e86f..00000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,147 +0,0 @@ -cmake_minimum_required(VERSION 3.27...3.28 FATAL_ERROR) - -cmake_policy(SET CMP0135 NEW) - -project(mkl_umath - LANGUAGES C - DESCRIPTION "mkl_umath module" -) - -option(OPTIMIZATION_REPORT - "Whether to generate optimization vectorization report" - OFF -) - -find_package(Python COMPONENTS Interpreter Development NumPy REQUIRED) - -# Print out the discovered paths -include(CMakePrintHelpers) -cmake_print_variables(Python_INCLUDE_DIRS) -cmake_print_variables(Python_LIBRARIES) -cmake_print_variables(Python_NumPy_INCLUDE_DIRS) - -set(CYTHON_FLAGS "-t -w \"${CMAKE_SOURCE_DIR}\"") -find_package(Cython REQUIRED) - -find_package(TBB REQUIRED) -set(MKL_ARCH "intel64") -set(MKL_LINK "dynamic") -set(MKL_THREADING "tbb_thread") -set(MKL_INTERFACE "lp64") -find_package(MKL REQUIRED) - -if(WIN32) - string(CONCAT WARNING_FLAGS - "-Wall " - "-Wextra " - "-Winit-self " - "-Wunused-function " - "-Wuninitialized " - "-Wmissing-declarations " - "-Wstrict-prototypes " - "-Wno-unused-parameter " - "-Wno-implicit-function-declaration " - ) - string(CONCAT SDL_FLAGS - "/GS " - "/DynamicBase " - ) - string(CONCAT PRECISION_FLAGS - "/fp:precise " - "/Qimf-precision=high " - "/Qprotect-parens " - ) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Ox ${WARNING_FLAGS} ${SDL_FLAGS} ${PRECISION_FLAGS}") - set(CMAKE_C_FLAGS_DEBUG - "${CMAKE_C_FLAGS_DEBUG} ${WARNING_FLAGS} ${SDL_FLAGS} /fp:precise -O0 -g1 -DDEBUG" - ) - set(MKL_UMATH_LINKER_OPTIONS "LINKER:/NXCompat;LINKER:/DynamicBase") -elseif(UNIX) - string(CONCAT WARNING_FLAGS - "-Wall " - "-Wextra " - "-Winit-self " - "-Wunused-function " - "-Wuninitialized " - "-Wmissing-declarations " - "-Wstrict-prototypes " - "-Wno-unused-parameter " - "-fdiagnostics-color=auto " - ) - string(CONCAT SDL_FLAGS - "-fstack-protector " - "-fstack-protector-all " - "-fpic " - "-fPIC " - "-D_FORTIFY_SOURCE=2 " - "-Wformat " - "-Wformat-security " -# "-fno-strict-overflow " # no-strict-overflow is implied by -fwrapv - "-fno-delete-null-pointer-checks " - "-fwrapv " - ) - string(CONCAT CFLAGS - "${WARNING_FLAGS}" - "${SDL_FLAGS}" - ) - string(CONCAT PRECISION_FLAGS - "-fprotect-parens " - "-fimf-precision=high " - "-fno-fast-math " - ) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 ${CFLAGS} ${PRECISION_FLAGS}") - set(CMAKE_C_FLAGS_DEBUG - "${CMAKE_C_FLAGS_DEBUG} ${CFLAGS} -fno-fast-math -O0 -g1 -DDEBUG" - ) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-incompatible-function-pointer-types ${CFLAGS}") - set(MKL_UMATH_LINKER_OPTIONS "LINKER:-z,noexecstack,-z,relro,-z,now") -else() - message(FATAL_ERROR "Unsupported system.") -endif() - -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) -# set_property(GLOBAL PROPERTY GLOBAL_DEPENDS_DEBUG_MODE 1) -set(_linker_options ${MKL_UMATH_LINKER_OPTIONS}) - -set(_trgt mkl_umath_loops) -add_library(${_trgt} SHARED mkl_umath/src/mkl_umath_loops.c) -set_target_properties(${_trgt} PROPERTIES - CMAKE_POSITION_INDEPENDENT_CODE ON - C_STANDARD 99 -) -target_include_directories(${_trgt} PUBLIC mkl_umath/src/ ${Python_NumPy_INCLUDE_DIRS} ${Python_INCLUDE_DIRS}) -target_link_libraries(${_trgt} PUBLIC MKL::MKL ${Python_LIBRARIES}) -target_link_options(${_trgt} PUBLIC ${_linker_options}) -target_compile_options(${_trgt} PUBLIC -fveclib=SVML) -target_compile_options(${_trgt} PUBLIC -fvectorize) -if(OPTIMIZATION_REPORT) - target_compile_options(${_trgt} PRIVATE -qopt-report=3) -endif() -install(TARGETS ${_trgt} - LIBRARY DESTINATION mkl_umath - ARCHIVE DESTINATION mkl_umath - RUNTIME DESTINATION mkl_umath -) - -python_add_library(_ufuncs MODULE WITH_SOABI "mkl_umath/src/ufuncsmodule.c" "mkl_umath/src/__umath_generated.c") -target_include_directories(_ufuncs PRIVATE "mkl_umath/src" ${Python_NumPy_INCLUDE_DIRS} ${MKL_INCLUDE_DIR}) -target_compile_definitions(_ufuncs PUBLIC NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION) -target_link_options(_ufuncs PRIVATE ${_linker_options}) -target_link_libraries(_ufuncs PRIVATE mkl_umath_loops) -set_target_properties(_ufuncs PROPERTIES C_STANDARD 99) -if (UNIX) - set_target_properties(_ufuncs PROPERTIES INSTALL_RPATH "$ORIGIN/../..;$ORIGIN/../../..;$ORIGIN") -endif() -install(TARGETS _ufuncs LIBRARY DESTINATION mkl_umath) - -add_cython_target(_patch "mkl_umath/src/_patch.pyx" C OUTPUT_VAR _generated_src) -Python_add_library(_patch MODULE WITH_SOABI ${_generated_src}) -target_include_directories(_patch PRIVATE "mkl_umath/src/" ${Python_NumPy_INCLUDE_DIRS} ${Python_INCLUDE_DIRS}) -target_compile_definitions(_patch PUBLIC NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION) -target_link_libraries(_patch PRIVATE mkl_umath_loops) -set_target_properties(_patch PROPERTIES C_STANDARD 99) -if (UNIX) - set_target_properties(_patch PROPERTIES INSTALL_RPATH "$ORIGIN/../..;$ORIGIN/../../..;$ORIGIN") -endif() -install(TARGETS _patch LIBRARY DESTINATION mkl_umath) diff --git a/_vendored/README.md b/_vendored/README.md index b3f3a919..42ec7946 100644 --- a/_vendored/README.md +++ b/_vendored/README.md @@ -1,5 +1,3 @@ ## Vendored files -File `conv_template.py` is copied from NumPy's numpy/distutils folder, since -`numpy.distutils` is absent from the installation layout starting with -Python 3.12 +Files `conv_template.py` and `process_src_template.py` are copied from NumPy's numpy/numpy/_build_utils folder diff --git a/_vendored/conv_template.py b/_vendored/conv_template.py index c8933d1d..3f634737 100644 --- a/_vendored/conv_template.py +++ b/_vendored/conv_template.py @@ -82,8 +82,8 @@ __all__ = ['process_str', 'process_file'] import os -import sys import re +import sys # names for replacement that are already global. global_names = {} @@ -106,12 +106,12 @@ def parse_structure(astr, level): at zero. Returns an empty list if no loops found. """ - if level == 0 : + if level == 0: loopbeg = "/**begin repeat" loopend = "/**end repeat**/" - else : - loopbeg = "/**begin repeat%d" % level - loopend = "/**end repeat%d**/" % level + else: + loopbeg = f"/**begin repeat{level}" + loopend = f"/**end repeat{level}**/" ind = 0 line = 0 @@ -124,9 +124,9 @@ def parse_structure(astr, level): start2 = astr.find("\n", start2) fini1 = astr.find(loopend, start2) fini2 = astr.find("\n", fini1) - line += astr.count("\n", ind, start2+1) - spanlist.append((start, start2+1, fini1, fini2+1, line)) - line += astr.count("\n", start2+1, fini2) + line += astr.count("\n", ind, start2 + 1) + spanlist.append((start, start2 + 1, fini1, fini2 + 1, line)) + line += astr.count("\n", start2 + 1, fini2) ind = fini2 spanlist.sort() return spanlist @@ -135,10 +135,13 @@ def parse_structure(astr, level): def paren_repl(obj): torep = obj.group(1) numrep = obj.group(2) - return ','.join([torep]*int(numrep)) + return ','.join([torep] * int(numrep)) + parenrep = re.compile(r"\(([^)]*)\)\*(\d+)") plainrep = re.compile(r"([^*]+)\*(\d+)") + + def parse_values(astr): # replaces all occurrences of '(a,b,c)*4' in astr # with 'a,b,c,a,b,c,a,b,c,a,b,c'. Empty braces generate @@ -155,7 +158,7 @@ def parse_values(astr): named_re = re.compile(r"#\s*(\w*)\s*=([^#]*)#") exclude_vars_re = re.compile(r"(\w*)=(\w*)") exclude_re = re.compile(":exclude:") -def parse_loop_header(loophead) : +def parse_loop_header(loophead): """Find all named replacements in the header Returns a list of dictionaries, one for each loop iteration, @@ -179,14 +182,13 @@ def parse_loop_header(loophead) : name = rep[0] vals = parse_values(rep[1]) size = len(vals) - if nsub is None : + if nsub is None: nsub = size - elif nsub != size : + elif nsub != size: msg = "Mismatch in number of values, %d != %d\n%s = %s" raise ValueError(msg % (nsub, size, name, vals)) names.append((name, vals)) - # Find any exclude variables excludes = [] @@ -200,30 +202,33 @@ def parse_loop_header(loophead) : # generate list of dictionaries, one for each template iteration dlist = [] - if nsub is None : + if nsub is None: raise ValueError("No substitution variables found") for i in range(nsub): tmp = {name: vals[i] for name, vals in names} dlist.append(tmp) return dlist + replace_re = re.compile(r"@(\w+)@") -def parse_string(astr, env, level, line) : - lineno = "#line %d\n" % line + + +def parse_string(astr, env, level, line): + lineno = f"#line {line}\n" # local function for string replacement, uses env def replace(match): name = match.group(1) - try : + try: val = env[name] except KeyError: - msg = 'line %d: no definition of key "%s"'%(line, name) + msg = f'line {line}: no definition of key "{name}"' raise ValueError(msg) from None return val code = [lineno] struct = parse_structure(astr, level) - if struct : + if struct: # recurse over inner loops oldend = 0 newlevel = level + 1 @@ -234,18 +239,18 @@ def replace(match): oldend = sub[3] newline = line + sub[4] code.append(replace_re.sub(replace, pref)) - try : + try: envlist = parse_loop_header(head) except ValueError as e: - msg = "line %d: %s" % (newline, e) + msg = f"line {newline}: {e}" raise ValueError(msg) - for newenv in envlist : + for newenv in envlist: newenv.update(env) newcode = parse_string(text, newenv, newlevel, newline) code.extend(newcode) suff = astr[oldend:] code.append(replace_re.sub(replace, suff)) - else : + else: # replace keys code.append(replace_re.sub(replace, astr)) code.append('\n') @@ -284,8 +289,8 @@ def process_file(source): try: code = process_str(''.join(lines)) except ValueError as e: - raise ValueError('In "%s" loop at %s' % (sourcefile, e)) from None - return '#line 1 "%s"\n%s' % (sourcefile, code) + raise ValueError(f'In "{sourcefile}" loop at {e}') from None + return f'#line 1 "{sourcefile}"\n{code}' def unique_key(adict): @@ -321,9 +326,10 @@ def main(): try: writestr = process_str(allstr) except ValueError as e: - raise ValueError("In %s loop at %s" % (file, e)) from None + raise ValueError(f"In {file} loop at {e}") from None outfile.write(writestr) + if __name__ == "__main__": main() diff --git a/_vendored/process_src_template.py b/_vendored/process_src_template.py new file mode 100644 index 00000000..f934c222 --- /dev/null +++ b/_vendored/process_src_template.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +import argparse +import importlib.util +import os + + +def get_processor(): + # Convoluted because we can't import from numpy + # (numpy is not yet built) + conv_template_path = os.path.join( + os.path.dirname(__file__), + 'conv_template.py' + ) + spec = importlib.util.spec_from_file_location( + 'conv_template', conv_template_path + ) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod.process_file + + +def process_and_write_file(fromfile, outfile): + """Process tempita templated file and write out the result. + + The template file is expected to end in `.src` + (e.g., `.c.src` or `.h.src`). + Processing `npy_somefile.c.src` generates `npy_somefile.c`. + + """ + process_file = get_processor() + content = process_file(fromfile) + with open(outfile, 'w') as f: + f.write(content) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + "infile", + type=str, + help="Path to the input file" + ) + parser.add_argument( + "-o", + "--outfile", + type=str, + help="Path to the output file" + ) + parser.add_argument( + "-i", + "--ignore", + type=str, + help="An ignored input - may be useful to add a " + "dependency between custom targets", + ) + args = parser.parse_args() + + if not args.infile.endswith('.src'): + raise ValueError(f"Unexpected extension: {args.infile}") + + outfile_abs = os.path.join(os.getcwd(), args.outfile) + process_and_write_file(args.infile, outfile_abs) + + +if __name__ == "__main__": + main() diff --git a/conda-recipe-cf/build.sh b/conda-recipe-cf/build.sh index 00414a1c..23ab8731 100644 --- a/conda-recipe-cf/build.sh +++ b/conda-recipe-cf/build.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e # This is necessary to help DPC++ find Intel libraries such as SVML, IRNG, etc in build prefix export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${BUILD_PREFIX}/lib" @@ -11,21 +12,28 @@ export ICXCFG read -r GLIBC_MAJOR GLIBC_MINOR <<< "$(conda list '^sysroot_linux-64$' \ | tail -n 1 | awk '{print $2}' | grep -oP '\d+' | head -n 2 | tr '\n' ' ')" -export CMAKE_GENERATOR="Ninja" -SKBUILD_ARGS=( - "--" - "-DCMAKE_C_COMPILER:PATH=icx" - "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" -) +if [-d "build"]; then + rm -rf build +fi + +export CC=icx +export CXX=icpx + +${PYTHON} -m build -w -n -x + +${PYTHON} -m wheel tags --remove \ + --platform "manylinux_${GLIBC_MAJOR}_${GLIBC_MINOR}_x86_64" \ + dist/mkl_umath*.whl + +${PYTHON} -m pip install dist/mkl_umath*.whl \ + --no-build-isolation \ + --no-deps \ + --only-binary :all: \ + --no-index \ + --prefix "${PREFIX}" + -vv if [ -n "${WHEELS_OUTPUT_FOLDER}" ]; then - # Install packages and assemble wheel package from built bits - WHEELS_BUILD_ARGS=( - "-p" "manylinux_${GLIBC_MAJOR}_${GLIBC_MINOR}_x86_64" - ) - ${PYTHON} setup.py install bdist_wheel "${WHEELS_BUILD_ARGS[@]}" "${SKBUILD_ARGS[@]}" + mkdir -p "${WHEELS_OUTPUT_FOLDER}" cp dist/mkl_umath*.whl "${WHEELS_OUTPUT_FOLDER}" -else - # Perform regular install - ${PYTHON} setup.py install "${SKBUILD_ARGS[@]}" fi diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml index 92d5a5db..2bed3179 100644 --- a/conda-recipe-cf/meta.yaml +++ b/conda-recipe-cf/meta.yaml @@ -20,12 +20,12 @@ requirements: - {{ compiler('dpcpp') }} >=2024.2 # [not osx] - sysroot_linux-64 >=2.28 # [linux] host: - - setuptools >=77 - - cmake + - meson-python >=0.13.0 + - meson + - pkg-config - ninja - git - cython - - scikit-build - python - mkl-devel - tbb-devel diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh index 00414a1c..23ab8731 100644 --- a/conda-recipe/build.sh +++ b/conda-recipe/build.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e # This is necessary to help DPC++ find Intel libraries such as SVML, IRNG, etc in build prefix export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${BUILD_PREFIX}/lib" @@ -11,21 +12,28 @@ export ICXCFG read -r GLIBC_MAJOR GLIBC_MINOR <<< "$(conda list '^sysroot_linux-64$' \ | tail -n 1 | awk '{print $2}' | grep -oP '\d+' | head -n 2 | tr '\n' ' ')" -export CMAKE_GENERATOR="Ninja" -SKBUILD_ARGS=( - "--" - "-DCMAKE_C_COMPILER:PATH=icx" - "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" -) +if [-d "build"]; then + rm -rf build +fi + +export CC=icx +export CXX=icpx + +${PYTHON} -m build -w -n -x + +${PYTHON} -m wheel tags --remove \ + --platform "manylinux_${GLIBC_MAJOR}_${GLIBC_MINOR}_x86_64" \ + dist/mkl_umath*.whl + +${PYTHON} -m pip install dist/mkl_umath*.whl \ + --no-build-isolation \ + --no-deps \ + --only-binary :all: \ + --no-index \ + --prefix "${PREFIX}" + -vv if [ -n "${WHEELS_OUTPUT_FOLDER}" ]; then - # Install packages and assemble wheel package from built bits - WHEELS_BUILD_ARGS=( - "-p" "manylinux_${GLIBC_MAJOR}_${GLIBC_MINOR}_x86_64" - ) - ${PYTHON} setup.py install bdist_wheel "${WHEELS_BUILD_ARGS[@]}" "${SKBUILD_ARGS[@]}" + mkdir -p "${WHEELS_OUTPUT_FOLDER}" cp dist/mkl_umath*.whl "${WHEELS_OUTPUT_FOLDER}" -else - # Perform regular install - ${PYTHON} setup.py install "${SKBUILD_ARGS[@]}" fi diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 38ea112f..2ed82777 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -19,12 +19,12 @@ requirements: - {{ stdlib('c') }} - {{ compiler('dpcpp') }} >=2024.2 # [not osx] host: - - setuptools >=77 - - cmake + - meson-python >=0.13.0 + - meson + - pkg-config - ninja - git - cython - - scikit-build - python - python-gil # [py>=314] - mkl-devel diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..552c15f4 --- /dev/null +++ b/meson.build @@ -0,0 +1,172 @@ +project( + 'mkl_umath', + ['c', 'cython'], + version: run_command( + 'python', '-c', + 'import os; exec(open("mkl_umath/_version.py").read()); print(__version__)', + check: true + ).stdout().strip(), + default_options: [ + 'c_std=c99', + 'buildtype=release', + 'b_ndebug=if-release' + ] +) + +py = import('python').find_installation(pure: false) + +# get includes +# numpy includes +np_dir = run_command(py, + ['-c', 'import numpy; print(numpy.get_include())'], + check: true +).stdout().strip() + +inc_np = include_directories(np_dir, 'mkl_umath/src') + +# Python headers needed for loops +py_dep = py.dependency() + +# compiler/linker +cc = meson.get_compiler('c') +c_args = [] +link_args = [] + +if get_option('opt_report') + if cc.get_id().startswith('intel') + c_args += 'qopt-report=3' + else + warning('Optimization report requested with non-Intel compiler') + endif +endif + +if cc.get_argument_syntax() == 'msvc' + c_args += [ + '/Ox', '/GS', '/DynamicBase', + '/fp:precise', 'Qimf-precision=high', '/Qprotect-parens' + ] + link_args = ['/NXCompat', '/DynamicBase'] +elif cc.get_argument_syntax() == 'gcc' + c_args += [ + '-O3', '-Wall', '-Wextra', '-Winit-self', '-Wunused-function', + '-Wuninitialized', '-Wmissing-declarations', '-Wstrict-prototypes', + '-Wno-unused-parameter', '-fdiagnostics-color=auto', + '-fstack-protector', '-fstack-protector-all', '-fpic', '-fPIC', + '-D_FORTIFY_SOURCE=2', '-Wformat', '-Wformat-security', + '-fno-delete-null-pointer-checks', '-fwrapv', + '-fprotect-parens', '-fimf-precision=high', '-fno-fast-math', + '-Wno-incompatible-function-pointer-types' + ] + link_args += ['-Wl,-z,noexecstack', '-Wl,-z,relro', '-Wl,-z,now'] +else + error('Unsupported system.') +endif + +# vectorization flags +c_args += ['-fveclib=SVML', '-fvectorize'] + +# dependencies +tbb_dep = dependency('tbb', required: true) + +# manually waterfall the meson deps: pkg-config to cmake to find_library +mkl_dep = dependency('mkl-dynamic-lp64-tbb', required: false) + +if not mkl_dep.found() + mkl_dep = dependency('MKL', method: 'cmake', + modules: ['MKL::MKL'], + cmake_args: [ + '-DMKL_ARCH=intel64', + '-DMKL_LINK=dynamic', + '-DMKL_THREADING=tbb_thread', + '-DMKL_INTERFACE=lp64' + ], + required: false + ) +endif + +if not mkl_dep.found() + # use static: false to emulate -DMKL_LINK=dynamic + # static: false docs are wrong, this will only consider shared libs + # see: https://github.com/mesonbuild/meson/issues/14163 + mkl_core = cc.find_library('mkl_core', required: true, static: false) + mkl_intel_lp64 = cc.find_library('mkl_intel_lp64', required: true, static: false) + mkl_tbb_thread = cc.find_library('mkl_tbb_thread', required: true, static: false) + mkl_dep = declare_dependency(dependencies: [mkl_core, mkl_intel_lp64, mkl_tbb_thread]) +endif + +# generate loops, similar to numpy +src_file_cli = find_program('_vendored/process_src_template.py') + +src_file = generator( + src_file_cli, + arguments: ['@INPUT@', '-o', '@OUTPUT@'], + output: '@BASENAME@' +) + +gen_loops_c = src_file.process('mkl_umath/src/mkl_umath_loops.c.src') +gen_loops_h = src_file.process('mkl_umath/src/mkl_umath_loops.h.src') + +gen_umath_c = custom_target( + '__umath_generated', + output: '__umath_generated.c', + input: 'mkl_umath/generate_umath.py', + command: [py, '@INPUT@', '-o', '@OUTPUT@'] +) + +mkl_umath_loops = shared_library( + 'mkl_umath_loops', + sources: [gen_loops_c, gen_loops_h], + include_directories: inc_np, + dependencies: [mkl_dep, tbb_dep, py_dep], + c_args: c_args, + link_args: link_args, + install: true, + install_dir: py.get_install_dir() / 'mkl_umath' +) + +loops_dep = declare_dependency(link_with: mkl_umath_loops) + +# extension modules + +ext_rpath = '' +if host_machine.system() != 'windows' + ext_rpath = '$ORIGIN/../..:$ORIGIN/../../..:$ORIGIN' +endif + +# gen_loops_h is generated by custom target so must be included in sources +py.extension_module( + '_ufuncs', + sources: ['mkl_umath/src/ufuncsmodule.c', gen_umath_c, gen_loops_h], + include_directories: inc_np, + dependencies: [mkl_dep, tbb_dep, loops_dep], + c_args: c_args + ['-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION'], + link_args: link_args, + install_rpath: ext_rpath, + install: true, + subdir: 'mkl_umath' +) + +py.extension_module( + '_patch', + sources: ['mkl_umath/src/_patch.pyx'], + include_directories: inc_np, + dependencies: [loops_dep], + c_args: c_args + ['-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION'], + cython_args: ['-3', '--fast-fail'], + link_args: link_args, + install_rpath: ext_rpath, + install: true, + subdir: 'mkl_umath' +) + +# install python sources + +py.install_sources( + [ + 'mkl_umath/__init__.py', + 'mkl_umath/_init_helper.py', + 'mkl_umath/_version.py', + 'mkl_umath/generate_umath.py' + ], + subdir: 'mkl_umath' +) diff --git a/meson.options b/meson.options new file mode 100644 index 00000000..4117cabc --- /dev/null +++ b/meson.options @@ -0,0 +1,2 @@ +option('opt_report', type: 'boolean', value: false, + description: 'Whether to generate optimization vectorization report') diff --git a/mkl_umath/generate_umath.py b/mkl_umath/generate_umath.py index 31be813e..c1325157 100644 --- a/mkl_umath/generate_umath.py +++ b/mkl_umath/generate_umath.py @@ -1152,7 +1152,7 @@ def make_ufuncs(funcdict): if uf.signature is None: sig = "NULL" else: - sig = '"{}"'.format(uf.signature) + sig = f'"{uf.signature}"' fmt = textwrap.dedent("""\ identity = {identity_expr}; if ({has_identity} && identity == NULL) {{ diff --git a/mkl_umath/ufunc_docstrings_numpy1.py b/mkl_umath/ufunc_docstrings_numpy1.py index 39efaee7..8e7aeb96 100644 --- a/mkl_umath/ufunc_docstrings_numpy1.py +++ b/mkl_umath/ufunc_docstrings_numpy1.py @@ -82,9 +82,9 @@ def add_newdoc(place, name, doc): ) if name[0] != "_" and name not in skip: if "\nx :" in doc: - assert "$OUT_SCALAR_1" in doc, "in {}".format(name) + assert "$OUT_SCALAR_1" in doc, f"in {name}" elif "\nx2 :" in doc or "\nx1, x2 :" in doc: - assert "$OUT_SCALAR_2" in doc, "in {}".format(name) + assert "$OUT_SCALAR_2" in doc, f"in {name}" else: raise AssertionError(f"Could not detect number of inputs in {name}") diff --git a/pyproject.toml b/pyproject.toml index af289e94..e88fa59a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,12 +24,10 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [build-system] -build-backend = "setuptools.build_meta" +build-backend = "mesonpy" requires = [ - "cmake", + "meson-python>=0.13.0", "ninja", - "scikit-build", - "setuptools>=77", "Cython", "numpy" ] @@ -89,10 +87,3 @@ line_length = 80 multi_line_output = 3 skip = ["_vendored/conv_template.py"] use_parentheses = true - -[tool.setuptools] -include-package-data = true -packages = ["mkl_umath"] - -[tool.setuptools.dynamic] -version = {attr = "mkl_umath._version.__version__"} diff --git a/setup.py b/setup.py deleted file mode 100644 index 2eef2e14..00000000 --- a/setup.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright (c) 2019, Intel Corporation -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of Intel Corporation nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import importlib.machinery -import sys -from os import makedirs -from os.path import dirname, exists, join - -import skbuild -from setuptools.modified import newer - -sys.path.insert(0, dirname(__file__)) # Ensures local imports work -from _vendored.conv_template import process_file as process_c_file # noqa: E402 - - -# TODO: rewrite generation in CMake, see NumPy meson implementation -# https://github.com/numpy/numpy/blob/c6fb3357541fd8cf6e4faeaeda3b1a9065da0520/numpy/_core/meson.build#L623 -def load_module(name, fn): - """Credit: numpy.compat.npy_load_module""" - return importlib.machinery.SourceFileLoader(name, fn).load_module(name) - - -def separator_join(sep, strs): - """ - Joins non-empty arguments strings with dot. - - Credit: numpy.distutils.misc_util.dot_join - """ - assert isinstance(strs, (list, tuple)) - assert isinstance(sep, str) - return sep.join([si for si in strs if si]) - - -pdir = join(dirname(__file__), "mkl_umath") -wdir = join(pdir, "src") - -generate_umath_py = join(pdir, "generate_umath.py") -n = separator_join("_", ("mkl_umath", "generate_umath")) -generate_umath = load_module(n, generate_umath_py) -del n - - -def generate_umath_c(build_dir): - target_dir = join(build_dir, "src") - target = join(target_dir, "__umath_generated.c") - if not exists(target_dir): - print( - "Folder {} was expected to exist, but creating".format(target_dir) - ) - makedirs(target_dir) - script = generate_umath_py - if newer(script, target): - with open(target, "w") as f: - f.write( - generate_umath.make_code( - generate_umath.defdict, generate_umath.__file__ - ) - ) - return [] - - -generate_umath_c(pdir) - -loops_header_templ = join(wdir, "mkl_umath_loops.h.src") -processed_loops_h_fn = join(wdir, "mkl_umath_loops.h") -loops_header_processed = process_c_file(loops_header_templ) - -with open(processed_loops_h_fn, "w") as fid: - fid.write(loops_header_processed) - -loops_src_templ = join(wdir, "mkl_umath_loops.c.src") -processed_loops_src_fn = join(wdir, "mkl_umath_loops.c") -loops_src_processed = process_c_file(loops_src_templ) - -with open(processed_loops_src_fn, "w") as fid: - fid.write(loops_src_processed) - - -skbuild.setup( - packages=[ - "mkl_umath", - ], - package_data={"mkl_umath": ["tests/*.*"]}, - include_package_data=True, -) From df4b85d44409fee710d3547e62f0878fedca47ef Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Tue, 3 Mar 2026 22:51:22 -0800 Subject: [PATCH 02/22] add tests to module --- meson.build | 5 +++++ mkl_umath/tests/__init__.py | 1 + 2 files changed, 6 insertions(+) create mode 100644 mkl_umath/tests/__init__.py diff --git a/meson.build b/meson.build index 552c15f4..a45f1b0a 100644 --- a/meson.build +++ b/meson.build @@ -170,3 +170,8 @@ py.install_sources( ], subdir: 'mkl_umath' ) + +install_subdir( + 'mkl_umath/tests', + install_dir: py.get_install_dir() / 'mkl_umath' +) diff --git a/mkl_umath/tests/__init__.py b/mkl_umath/tests/__init__.py new file mode 100644 index 00000000..fa81adaf --- /dev/null +++ b/mkl_umath/tests/__init__.py @@ -0,0 +1 @@ +# empty file From 0c8cb8be954a793858fea83c97536ba6252a85c4 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Tue, 3 Mar 2026 23:08:35 -0800 Subject: [PATCH 03/22] exclude process_src_template from linting --- .flake8 | 4 +++- pyproject.toml | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.flake8 b/.flake8 index 36cf71be..4c55551e 100644 --- a/.flake8 +++ b/.flake8 @@ -26,7 +26,9 @@ per-file-ignores = mkl_umath/ufunc_docstrings_numpy1.py: E501 mkl_umath/ufunc_docstrings_numpy2.py: E501 -exclude = _vendored/conv_template.py +exclude = + _vendored/conv_template.py + _vendored/process_src_template.py filename = *.py, *.pyx, *.pxi, *.pxd max_line_length = 80 diff --git a/pyproject.toml b/pyproject.toml index e88fa59a..0c080c56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,7 @@ Download = "http://github.com/IntelPython/mkl_umath" Homepage = "http://github.com/IntelPython/mkl_umath" [tool.black] -exclude = "_vendored/conv_template.py" +extend-exclude = "_vendored/" line-length = 80 [tool.cython-lint] @@ -85,5 +85,5 @@ force_grid_wrap = 0 include_trailing_comma = true line_length = 80 multi_line_output = 3 -skip = ["_vendored/conv_template.py"] +skip = ["_vendored/conv_template.py", "_vendored/process_src_template.py"] use_parentheses = true From e1571bf33ff368f281f0f658430b4ce6702ab6cd Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Tue, 3 Mar 2026 23:24:35 -0800 Subject: [PATCH 04/22] add python-build to meta.yamls also fix license in pyproject.toml --- conda-recipe-cf/meta.yaml | 2 ++ conda-recipe/meta.yaml | 1 + pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml index 2bed3179..056cf57a 100644 --- a/conda-recipe-cf/meta.yaml +++ b/conda-recipe-cf/meta.yaml @@ -27,6 +27,8 @@ requirements: - git - cython - python + - python-gil # [py>=314] + - python-build - mkl-devel - tbb-devel - numpy diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 2ed82777..6cab0c07 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -27,6 +27,7 @@ requirements: - cython - python - python-gil # [py>=314] + - python-build - mkl-devel - tbb-devel - numpy-base diff --git a/pyproject.toml b/pyproject.toml index 0c080c56..82a1e8fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,7 +59,7 @@ dependencies = ["numpy >=1.26.4", "mkl-service"] description = "Intel (R) MKL-based universal functions for NumPy arrays" dynamic = ["version"] keywords = ["mkl_umath"] -license = "BSD-3-Clause" +license = {text = "BSD-3-Clause"} name = "mkl_umath" readme = {file = "README.md", content-type = "text/markdown"} requires-python = ">=3.10,<3.15" From db852b71a2d239a279dce8e87e29036a9fe410a7 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 14:48:18 -0800 Subject: [PATCH 05/22] fix syntax in build shell scripts --- conda-recipe-cf/build.sh | 4 ++-- conda-recipe/build.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/conda-recipe-cf/build.sh b/conda-recipe-cf/build.sh index 23ab8731..3b7f73d6 100644 --- a/conda-recipe-cf/build.sh +++ b/conda-recipe-cf/build.sh @@ -12,7 +12,7 @@ export ICXCFG read -r GLIBC_MAJOR GLIBC_MINOR <<< "$(conda list '^sysroot_linux-64$' \ | tail -n 1 | awk '{print $2}' | grep -oP '\d+' | head -n 2 | tr '\n' ' ')" -if [-d "build"]; then +if [ -d "build" ]; then rm -rf build fi @@ -30,7 +30,7 @@ ${PYTHON} -m pip install dist/mkl_umath*.whl \ --no-deps \ --only-binary :all: \ --no-index \ - --prefix "${PREFIX}" + --prefix "${PREFIX}" \ -vv if [ -n "${WHEELS_OUTPUT_FOLDER}" ]; then diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh index 23ab8731..3b7f73d6 100644 --- a/conda-recipe/build.sh +++ b/conda-recipe/build.sh @@ -12,7 +12,7 @@ export ICXCFG read -r GLIBC_MAJOR GLIBC_MINOR <<< "$(conda list '^sysroot_linux-64$' \ | tail -n 1 | awk '{print $2}' | grep -oP '\d+' | head -n 2 | tr '\n' ' ')" -if [-d "build"]; then +if [ -d "build" ]; then rm -rf build fi @@ -30,7 +30,7 @@ ${PYTHON} -m pip install dist/mkl_umath*.whl \ --no-deps \ --only-binary :all: \ --no-index \ - --prefix "${PREFIX}" + --prefix "${PREFIX}" \ -vv if [ -n "${WHEELS_OUTPUT_FOLDER}" ]; then From 82ac8f6186c7ab875e5cf6c7c5b9cb6681b9acf5 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 14:50:15 -0800 Subject: [PATCH 06/22] update build_pip workflow --- .github/workflows/build_pip.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/build_pip.yaml b/.github/workflows/build_pip.yaml index 511a54cf..db5192e0 100644 --- a/.github/workflows/build_pip.yaml +++ b/.github/workflows/build_pip.yaml @@ -48,10 +48,8 @@ jobs: - name: Build conda package run: | - pip install --no-cache-dir scikit-build cmake ninja cython + pip install --no-cache-dir meson-python ninja cython pip install --no-cache-dir numpy ${{ matrix.use_pre }} - echo "CONDA_PREFFIX is '${CONDA_PREFIX}'" - export MKLROOT=${CONDA_PREFIX} CC=icx pip install . --no-build-isolation --no-deps --verbose pip install --no-cache-dir pytest pip list From 140005f99c863ac4a44a16ebbe2e6d250a14bc97 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 17:24:11 -0800 Subject: [PATCH 07/22] update clang workflow add workflow using standard clang --- .github/workflows/build-with-clang.yml | 5 +- .../workflows/build-with-standard-clang.yml | 64 +++++++++++++++++++ meson.build | 15 +++-- mkl_umath/src/mkl_umath_loops.c.src | 2 +- 4 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/build-with-standard-clang.yml diff --git a/.github/workflows/build-with-clang.yml b/.github/workflows/build-with-clang.yml index 251747da..434a6dce 100644 --- a/.github/workflows/build-with-clang.yml +++ b/.github/workflows/build-with-clang.yml @@ -8,7 +8,7 @@ on: permissions: read-all jobs: - build-with-clang: + build-with-intel-clang: runs-on: ubuntu-latest strategy: @@ -56,7 +56,7 @@ jobs: - name: Install mkl_umath dependencies run: | - pip install scikit-build cmake ninja cython setuptools">=77" + pip install meson-python ninja cython mkl-service pip install ${{ matrix.numpy_version }} - name: List oneAPI folder content @@ -67,7 +67,6 @@ jobs: source ${{ env.ONEAPI_ROOT }}/setvars.sh echo "$CMPLR_ROOT" export CC="$CMPLR_ROOT/bin/icx" - export CFLAGS="${CFLAGS} -fno-fast-math -O2" pip install . --no-build-isolation --no-deps --verbose - name: Run mkl_umath tests diff --git a/.github/workflows/build-with-standard-clang.yml b/.github/workflows/build-with-standard-clang.yml new file mode 100644 index 00000000..40503067 --- /dev/null +++ b/.github/workflows/build-with-standard-clang.yml @@ -0,0 +1,64 @@ +name: Build project with standard clang compiler + +on: + pull_request: + push: + branches: [master] + +permissions: read-all + +jobs: + build-with-standard-clang: + runs-on: ubuntu-latest + + strategy: + matrix: + python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + numpy_version: ["numpy'>=2'"] + + env: + COMPILER_ROOT: /usr/bin + + defaults: + run: + shell: bash -el {0} + + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@3155a141048f8f89c06b4cdae32e7853e97536bc # 0.13.0 + with: + access_token: ${{ github.token }} + + - name: Install Dependencies + run: | + sudo apt-get update && sudo apt-get install -y clang + + - name: Setup Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: ${{ matrix.python }} + architecture: x64 + + - name: Checkout repo + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - name: Install mkl_umath dependencies + run: | + pip install meson-python ninja cython mkl-service + pip install mkl-devel tbb-devel + pip install ${{ matrix.numpy_version }} + + - name: Build mkl_umath + run: | + export CC=${{ env.COMPILER_ROOT }}/clang + pip install . --no-build-isolation --no-deps --verbose + + - name: Run mkl_umath tests + run: | + pip install pytest + # mkl_umath cannot be installed in editable mode, we need + # to change directory before importing it and running tests + cd .. + python -m pytest -sv --pyargs mkl_umath/mkl_umath/tests diff --git a/meson.build b/meson.build index a45f1b0a..aa930354 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project( 'mkl_umath', - ['c', 'cython'], + ['c', 'cpp', 'cython'], version: run_command( 'python', '-c', 'import os; exec(open("mkl_umath/_version.py").read()); print(__version__)', @@ -42,10 +42,13 @@ endif if cc.get_argument_syntax() == 'msvc' c_args += [ - '/Ox', '/GS', '/DynamicBase', - '/fp:precise', 'Qimf-precision=high', '/Qprotect-parens' + '/Ox', '/GS', '/DynamicBase', '/fp:precise' ] link_args = ['/NXCompat', '/DynamicBase'] + + if cc.get_id().startswith('intel') + c_args += ['Qimf-precision=high', '/Qprotect-parens'] + endif elif cc.get_argument_syntax() == 'gcc' c_args += [ '-O3', '-Wall', '-Wextra', '-Winit-self', '-Wunused-function', @@ -53,11 +56,13 @@ elif cc.get_argument_syntax() == 'gcc' '-Wno-unused-parameter', '-fdiagnostics-color=auto', '-fstack-protector', '-fstack-protector-all', '-fpic', '-fPIC', '-D_FORTIFY_SOURCE=2', '-Wformat', '-Wformat-security', - '-fno-delete-null-pointer-checks', '-fwrapv', - '-fprotect-parens', '-fimf-precision=high', '-fno-fast-math', + '-fno-delete-null-pointer-checks', '-fwrapv', '-fno-fast-math', '-Wno-incompatible-function-pointer-types' ] link_args += ['-Wl,-z,noexecstack', '-Wl,-z,relro', '-Wl,-z,now'] + if cc.get_id().startswith('intel') + c_args += ['-fimf-precision=high', '-fprotect-parens'] + endif else error('Unsupported system.') endif diff --git a/mkl_umath/src/mkl_umath_loops.c.src b/mkl_umath/src/mkl_umath_loops.c.src index b588ca6f..5131d620 100644 --- a/mkl_umath/src/mkl_umath_loops.c.src +++ b/mkl_umath/src/mkl_umath_loops.c.src @@ -151,7 +151,7 @@ static inline npy_double spacing(npy_double x) { } static inline npy_float spacingf(npy_float x) { - if (isinff(x)) + if (isinf(x)) return ((npy_float) NAN); return copysignf(nextafterf(fabsf(x), INFINITY), x) - x; From 74774e5ef13a2ec5d352afa62effe1832ca857dc Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 19:28:41 -0800 Subject: [PATCH 08/22] fix import error in builds --- .github/workflows/build-with-clang.yml | 2 +- .github/workflows/build-with-standard-clang.yml | 2 +- .github/workflows/build_pip.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-with-clang.yml b/.github/workflows/build-with-clang.yml index 434a6dce..06f9af8e 100644 --- a/.github/workflows/build-with-clang.yml +++ b/.github/workflows/build-with-clang.yml @@ -76,4 +76,4 @@ jobs: # mkl_umath cannot be installed in editable mode, we need # to change directory before importing it and running tests cd .. - python -m pytest -sv --pyargs mkl_umath/mkl_umath/tests + python -m pytest -sv --pyargs mkl_umath diff --git a/.github/workflows/build-with-standard-clang.yml b/.github/workflows/build-with-standard-clang.yml index 40503067..72998c0e 100644 --- a/.github/workflows/build-with-standard-clang.yml +++ b/.github/workflows/build-with-standard-clang.yml @@ -61,4 +61,4 @@ jobs: # mkl_umath cannot be installed in editable mode, we need # to change directory before importing it and running tests cd .. - python -m pytest -sv --pyargs mkl_umath/mkl_umath/tests + python -m pytest -sv --pyargs mkl_umath diff --git a/.github/workflows/build_pip.yaml b/.github/workflows/build_pip.yaml index db5192e0..9e170066 100644 --- a/.github/workflows/build_pip.yaml +++ b/.github/workflows/build_pip.yaml @@ -56,4 +56,4 @@ jobs: # mkl_umath cannot be installed in editable mode, we need # to change directory before importing it and running tests cd .. - python -m pytest -v mkl_umath/mkl_umath/tests + python -m pytest -sv --pyargs mkl_umath From d79b624ebdeec8bff9235cb95a977003877c2838 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 19:54:55 -0800 Subject: [PATCH 09/22] update Windows build scripts --- conda-recipe-cf/bld.bat | 30 +++++++++++++++--------------- conda-recipe/bld.bat | 27 +++++++++++++++++---------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/conda-recipe-cf/bld.bat b/conda-recipe-cf/bld.bat index e27318da..d2a5956e 100644 --- a/conda-recipe-cf/bld.bat +++ b/conda-recipe-cf/bld.bat @@ -2,24 +2,24 @@ REM A workaround for activate-dpcpp.bat issue to be addressed in 2021.4 set "LIB=%BUILD_PREFIX%\Library\lib;%BUILD_PREFIX%\compiler\lib;%LIB%" set "INCLUDE=%BUILD_PREFIX%\include;%INCLUDE%" -"%PYTHON%" setup.py clean --all -set "SKBUILD_ARGS=-G Ninja -- -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" +set "CC=icx" +set "CXX=icx" -FOR %%V IN (14.0.0 14 15.0.0 15 16.0.0 16 17.0.0 17) DO @( - REM set DIR_HINT if directory exists - IF EXIST "%BUILD_PREFIX%\Library\lib\clang\%%V\" ( - SET "SYCL_INCLUDE_DIR_HINT=%BUILD_PREFIX%\Library\lib\clang\%%V" - ) +%PYTHON% -m build -w -n -x +if %ERRORLEVEL% neq "0" exit 1 + +for /f %%f in ('dir /b /S .\dist') do ( + %PYTHON% -m pip install %%f ^ + --no-build-isolation ^ + --no-deps ^ + --only-binary :all: ^ + --no-index ^ + --prefix %PREFIX% ^ + -vv + if %ERRORLEVEL% neq 0 exit 1 ) if NOT "%WHEELS_OUTPUT_FOLDER%"=="" ( - rem Install and assemble wheel package from the build bits - "%PYTHON%" setup.py install bdist_wheel %SKBUILD_ARGS% - if errorlevel 1 exit 1 copy dist\mkl_umath*.whl %WHEELS_OUTPUT_FOLDER% - if errorlevel 1 exit 1 -) ELSE ( - rem Only install - "%PYTHON%" setup.py install %SKBUILD_ARGS% - if errorlevel 1 exit 1 + if %ERRORLEVEL% neq 0 exit 1 ) diff --git a/conda-recipe/bld.bat b/conda-recipe/bld.bat index 0616542f..d2a5956e 100644 --- a/conda-recipe/bld.bat +++ b/conda-recipe/bld.bat @@ -2,17 +2,24 @@ REM A workaround for activate-dpcpp.bat issue to be addressed in 2021.4 set "LIB=%BUILD_PREFIX%\Library\lib;%BUILD_PREFIX%\compiler\lib;%LIB%" set "INCLUDE=%BUILD_PREFIX%\include;%INCLUDE%" -"%PYTHON%" setup.py clean --all -set "SKBUILD_ARGS=-G Ninja -- -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON" +set "CC=icx" +set "CXX=icx" + +%PYTHON% -m build -w -n -x +if %ERRORLEVEL% neq "0" exit 1 + +for /f %%f in ('dir /b /S .\dist') do ( + %PYTHON% -m pip install %%f ^ + --no-build-isolation ^ + --no-deps ^ + --only-binary :all: ^ + --no-index ^ + --prefix %PREFIX% ^ + -vv + if %ERRORLEVEL% neq 0 exit 1 +) if NOT "%WHEELS_OUTPUT_FOLDER%"=="" ( - rem Install and assemble wheel package from the build bits - "%PYTHON%" setup.py install bdist_wheel %SKBUILD_ARGS% - if errorlevel 1 exit 1 copy dist\mkl_umath*.whl %WHEELS_OUTPUT_FOLDER% - if errorlevel 1 exit 1 -) ELSE ( - rem Only install - "%PYTHON%" setup.py install %SKBUILD_ARGS% - if errorlevel 1 exit 1 + if %ERRORLEVEL% neq 0 exit 1 ) From a7ffcd20b83eaf18672d9862e467efa937fc6e8a Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 20:22:10 -0800 Subject: [PATCH 10/22] fix linting --- .flake8 | 2 ++ pyproject.toml | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.flake8 b/.flake8 index 4c55551e..84cfe007 100644 --- a/.flake8 +++ b/.flake8 @@ -12,6 +12,8 @@ extend-ignore = D102, # missing docstring in public function: D103, + # missing docstring in public package: + D104, # missing docstring in __init__: D107, # 1 blank line required between summary line and description: diff --git a/pyproject.toml b/pyproject.toml index 82a1e8fd..01c6ea23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,8 @@ Download = "http://github.com/IntelPython/mkl_umath" Homepage = "http://github.com/IntelPython/mkl_umath" [tool.black] -extend-exclude = "_vendored/" +extend-exclude = "(^|/)_vendored/" +force-exclude = "(^|/)_vendored/" line-length = 80 [tool.cython-lint] From 55cf5ec1bea2c305994b8e232e58280d00150b9b Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 20:22:14 -0800 Subject: [PATCH 11/22] add conda-package-cf workflow tests against conda-forge packages --- .github/workflows/conda-package-cf.yml | 337 +++++++++++++++++++++++++ 1 file changed, 337 insertions(+) create mode 100644 .github/workflows/conda-package-cf.yml diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml new file mode 100644 index 00000000..0a473122 --- /dev/null +++ b/.github/workflows/conda-package-cf.yml @@ -0,0 +1,337 @@ +name: Conda package with conda-forge channel only + +on: + push: + branches: + - master + pull_request: + +permissions: read-all + +env: + PACKAGE_NAME: mkl_umath + VER_SCRIPT1: "import json; f = open('ver.json', 'r'); j = json.load(f); f.close(); d = j['mkl_umath'][0];" + VER_SCRIPT2: "print('='.join((d[s] for s in ('version', 'build'))))" + +jobs: + build_linux: + runs-on: ubuntu-latest + strategy: + matrix: + python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@3155a141048f8f89c06b4cdae32e7853e97536bc # 0.13.0 + with: + access_token: ${{ github.token }} + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - name: Set pkgs_dirs + run: | + echo "pkgs_dirs: [~/.conda/pkgs]" >> ~/.condarc + + - name: Cache conda packages + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + env: + CACHE_NUMBER: 0 # Increase to reset cache + with: + path: ~/.conda/pkgs + key: + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}-${{hashFiles('**/meta.yaml') }} + restore-keys: | + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}- + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}- + + - name: Add conda to system path + run: echo $CONDA/bin >> $GITHUB_PATH + + - name: Install conda-build + run: conda install conda-build + + - name: Build conda package + run: | + CHANNELS="-c conda-forge --override-channels" + VERSIONS="--python ${{ matrix.python }}" + TEST="--no-test" + echo "CONDA_BLD=${CONDA}/conda-bld/linux-64" >> $GITHUB_ENV + + conda build \ + $TEST \ + $VERSIONS \ + $CHANNELS \ + conda-recipe-cf + + - name: Upload artifact + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} + path: ${{ env.CONDA_BLD }}/${{ env.PACKAGE_NAME }}-*.conda + + test_linux: + needs: build_linux + runs-on: ${{ matrix.runner }} + + strategy: + matrix: + python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + experimental: [false] + runner: [ubuntu-latest] + continue-on-error: ${{ matrix.experimental }} + env: + CHANNELS: -c conda-forge --override-channels + + steps: + - name: Download artifact + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 + with: + name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} + - name: Add conda to system path + run: echo $CONDA/bin >> $GITHUB_PATH + - name: Install conda-build + run: conda install conda-build + - name: Create conda channel + run: | + mkdir -p $GITHUB_WORKSPACE/channel/linux-64 + mv ${PACKAGE_NAME}-*.conda $GITHUB_WORKSPACE/channel/linux-64 + conda index $GITHUB_WORKSPACE/channel + # Test channel + conda search $PACKAGE_NAME -c $GITHUB_WORKSPACE/channel --override-channels + + - name: Collect dependencies + run: | + CHANNELS="-c $GITHUB_WORKSPACE/channel ${{ env.CHANNELS }}" + conda create -n test_mkl_umath $PACKAGE_NAME python=${{ matrix.python }} $CHANNELS --only-deps --dry-run > lockfile + - name: Display lockfile + run: cat lockfile + + - name: Set pkgs_dirs + run: | + echo "pkgs_dirs: [~/.conda/pkgs]" >> ~/.condarc + + - name: Cache conda packages + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + env: + CACHE_NUMBER: 0 # Increase to reset cache + with: + path: ~/.conda/pkgs + key: + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}-${{hashFiles('lockfile') }} + restore-keys: | + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}- + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}- + + - name: Install mkl_umath + run: | + CHANNELS="-c $GITHUB_WORKSPACE/channel ${{ env.CHANNELS }}" + conda create -n test_mkl_umath python=${{ matrix.python }} $PACKAGE_NAME pytest $CHANNELS + # Test installed packages + conda list -n test_mkl_umath + + - name: Smoke test + run: | + source $CONDA/etc/profile.d/conda.sh + conda activate test_mkl_umath + python -c "import mkl_umath, numpy as np; mkl_umath.use_in_numpy(); np.sin(np.linspace(0, 1, num=10**6));" + + - name: Run tests + run: | + source $CONDA/etc/profile.d/conda.sh + conda activate test_mkl_umath + pytest -v --pyargs ${{ env.PACKAGE_NAME }} + + build_windows: + runs-on: windows-latest + + strategy: + matrix: + python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + env: + conda-bld: C:\Miniconda\conda-bld\win-64\ + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@3155a141048f8f89c06b4cdae32e7853e97536bc # 0.13.0 + with: + access_token: ${{ github.token }} + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: conda-incubator/setup-miniconda@fc2d68f6413eb2d87b895e92f8584b5b94a10167 # v3.3.0 + with: + miniforge-variant: Miniforge3 + miniforge-version: latest + activate-environment: build + channels: conda-forge + conda-remove-defaults: "true" + python-version: ${{ matrix.python }} + + - name: Cache conda packages + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + env: + CACHE_NUMBER: 3 # Increase to reset cache + with: + path: /home/runner/conda_pkgs_dir + key: + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}-${{hashFiles('**/meta.yaml') }} + restore-keys: | + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}- + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}- + + - name: Store conda paths as envs + shell: bash -l {0} + run: | + echo "CONDA_BLD=$CONDA/conda-bld/win-64/" | tr "\\\\" '/' >> $GITHUB_ENV + + - name: Install conda build + run: | + conda activate + conda install -y conda-build + conda list -n base + + - name: Build conda package + run: | + conda activate + conda build --no-test --python ${{ matrix.python }} -c conda-forge --override-channels conda-recipe-cf + + - name: Upload artifact + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} + path: ${{ env.CONDA_BLD }}${{ env.PACKAGE_NAME }}-*.conda + + test_windows: + needs: build_windows + runs-on: ${{ matrix.runner }} + defaults: + run: + shell: cmd /C CALL {0} + strategy: + matrix: + python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + experimental: [false] + runner: [windows-latest] + continue-on-error: ${{ matrix.experimental }} + env: + workdir: '${{ github.workspace }}' + CHANNELS: -c conda-forge --override-channels + + steps: + - name: Download artifact + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 + with: + name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} + + - uses: conda-incubator/setup-miniconda@fc2d68f6413eb2d87b895e92f8584b5b94a10167 # v3.3.0 + with: + miniforge-variant: Miniforge3 + miniforge-version: latest + activate-environment: mkl_umath_test + channels: conda-forge + conda-remove-defaults: "true" + python-version: ${{ matrix.python }} + + - name: Install conda-index + run: | + conda install -n base conda-index + + - name: Create conda channel with the artifact bit + shell: cmd /C CALL {0} + run: | + echo ${{ env.workdir }} + mkdir ${{ env.workdir }}\channel + mkdir ${{ env.workdir }}\channel\win-64 + move ${{ env.PACKAGE_NAME }}-*.conda ${{ env.workdir }}\channel\win-64 + dir ${{ env.workdir }}\channel\win-64 + + - name: Index the channel + shell: cmd /C CALL {0} + run: | + conda index ${{ env.workdir }}\channel + + - name: Dump mkl_umath version info from created channel to STDOUT + shell: cmd /C CALL {0} + run: | + conda search ${{ env.PACKAGE_NAME }} -c ${{ env.workdir }}/channel --override-channels --info --json + + - name: Dump mkl_umath version info from created channel into ver.json + shell: cmd /C CALL {0} + run: | + conda search ${{ env.PACKAGE_NAME }} -c ${{ env.workdir }}/channel --override-channels --info --json > ${{ env.workdir }}\ver.json + + - name: Output content of workdir + shell: pwsh + run: Get-ChildItem -Path ${{ env.workdir }} + + - name: Output content of produced ver.json + shell: pwsh + run: Get-Content -Path ${{ env.workdir }}\ver.json + + - name: Collect dependencies + shell: cmd /C CALL {0} + run: | + @ECHO ON + IF NOT EXIST ver.json ( + copy /Y ${{ env.workdir }}\ver.json . + ) + SET "SCRIPT=%VER_SCRIPT1% %VER_SCRIPT2%" + FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO ( + SET PACKAGE_VERSION=%%F + ) + conda install -n mkl_umath_test ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} --only-deps --dry-run > lockfile + + - name: Display lockfile content + shell: pwsh + run: Get-Content -Path .\lockfile + + - name: Cache conda packages + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + env: + CACHE_NUMBER: 0 # Increase to reset cache + with: + path: /home/runner/conda_pkgs_dir + key: + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}-${{hashFiles('lockfile') }} + restore-keys: | + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}- + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}- + + # add intel-openmp as an explicit dependency + # to avoid it being missed when package version is specified exactly + - name: Install mkl_umath + shell: cmd /C CALL {0} + run: | + @ECHO ON + IF NOT EXIST ver.json ( + copy /Y ${{ env.workdir }}\ver.json . + ) + set "SCRIPT=%VER_SCRIPT1% %VER_SCRIPT2%" + FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO ( + SET PACKAGE_VERSION=%%F + ) + SET "TEST_DEPENDENCIES=pytest pytest-cov" + SET "WORKAROUND_DEPENDENCIES=intel-openmp" + SET "DEPENDENCIES=%TEST_DEPENDENCIES% %WORKAROUND_DEPENDENCIES%" + conda install -n mkl_umath_test ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% %DEPENDENCIES% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} + + - name: Report content of test environment + shell: cmd /C CALL {0} + run: | + conda activate + echo "Value of CONDA environment variable was: " %CONDA% + echo "Value of CONDA_PREFIX environment variable was: " %CONDA_PREFIX% + conda info && conda list -n mkl_umath_test + + - name: Smoke test + shell: cmd /C CALL {0} + run: | + @ECHO ON + conda activate mkl_umath_test + python -c "import mkl_umath, numpy as np; mkl_umath.use_in_numpy(); np.sin(np.linspace(0, 1, num=10**6));" + + - name: Run tests + shell: cmd /C CALL {0} + run: | + conda activate mkl_umath_test + python -m pytest -v -s --pyargs ${{ env.PACKAGE_NAME }} From 480505bb5983b89a602fcb22eb9bdec1e9f94949 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 20:36:18 -0800 Subject: [PATCH 12/22] fix flags on windows builds --- meson.build | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index aa930354..23b0baa8 100644 --- a/meson.build +++ b/meson.build @@ -47,7 +47,9 @@ if cc.get_argument_syntax() == 'msvc' link_args = ['/NXCompat', '/DynamicBase'] if cc.get_id().startswith('intel') - c_args += ['Qimf-precision=high', '/Qprotect-parens'] + c_args += [ + '/Qimf-precision=high', '/Qprotect-parens', '/clang:-fveclib=SVML' + ] endif elif cc.get_argument_syntax() == 'gcc' c_args += [ @@ -61,15 +63,15 @@ elif cc.get_argument_syntax() == 'gcc' ] link_args += ['-Wl,-z,noexecstack', '-Wl,-z,relro', '-Wl,-z,now'] if cc.get_id().startswith('intel') - c_args += ['-fimf-precision=high', '-fprotect-parens'] + c_args += [ + '-fimf-precision=high', '-fprotect-parens', '-fveclib=SVML', + '-fvectorize' + ] endif else error('Unsupported system.') endif -# vectorization flags -c_args += ['-fveclib=SVML', '-fvectorize'] - # dependencies tbb_dep = dependency('tbb', required: true) From a9d47ae5dad948fce193b886cced6f3e5730389a Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 20:53:11 -0800 Subject: [PATCH 13/22] add python-gil to run requirements when building on conda-forge --- conda-recipe-cf/meta.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml index 056cf57a..8f74fce5 100644 --- a/conda-recipe-cf/meta.yaml +++ b/conda-recipe-cf/meta.yaml @@ -34,6 +34,8 @@ requirements: - numpy run: - python + - python-gil # [py>=314] + - mkl-service - {{ pin_compatible('intel-cmplr-lib-rt') }} test: From e9c2a95513d5a1b9559be486bd91b06b7069aced Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 22:30:23 -0800 Subject: [PATCH 14/22] fix conda-forge workflow build matrices --- .github/workflows/conda-package-cf.yml | 44 ++++++++++++++++++++------ conda-recipe-cf/meta.yaml | 2 ++ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index 0a473122..ea27592d 100644 --- a/.github/workflows/conda-package-cf.yml +++ b/.github/workflows/conda-package-cf.yml @@ -18,7 +18,18 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + include: + - python: "3.10" + numpy: "2.2" + - python: "3.11" + numpy: "2.3" + - python: "3.12" + numpy: "2.3" + - python: "3.13" + numpy: "2.3" + - python: "3.14" + numpy: "2.3" + steps: - name: Cancel Previous Runs uses: styfle/cancel-workflow-action@3155a141048f8f89c06b4cdae32e7853e97536bc # 0.13.0 @@ -50,17 +61,17 @@ jobs: - name: Install conda-build run: conda install conda-build - - name: Build conda package + - name: Build conda package with NumPy 2.x run: | - CHANNELS="-c conda-forge --override-channels" - VERSIONS="--python ${{ matrix.python }}" - TEST="--no-test" + CHANNELS=(-c conda-forge --override-channels) + VERSIONS=(--python "${{ matrix.python }}" --numpy "${{ matrix.numpy }}") + TEST=(--no-test) echo "CONDA_BLD=${CONDA}/conda-bld/linux-64" >> $GITHUB_ENV conda build \ - $TEST \ - $VERSIONS \ - $CHANNELS \ + "${TEST[@]}" \ + "${VERSIONS[@]}" \ + "${CHANNELS[@]}" \ conda-recipe-cf - name: Upload artifact @@ -76,6 +87,7 @@ jobs: strategy: matrix: python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + numpy: ['numpy">2"'] experimental: [false] runner: [ubuntu-latest] continue-on-error: ${{ matrix.experimental }} @@ -146,7 +158,18 @@ jobs: strategy: matrix: - python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + include: + - python: "3.10" + numpy: "2.2" + - python: "3.11" + numpy: "2.3" + - python: "3.12" + numpy: "2.3" + - python: "3.13" + numpy: "2.3" + - python: "3.14" + numpy: "2.3" + env: conda-bld: C:\Miniconda\conda-bld\win-64\ steps: @@ -193,7 +216,7 @@ jobs: - name: Build conda package run: | conda activate - conda build --no-test --python ${{ matrix.python }} -c conda-forge --override-channels conda-recipe-cf + conda build --no-test --python ${{ matrix.python }} --numpy ${{ matrix.numpy }} -c conda-forge --override-channels conda-recipe-cf - name: Upload artifact uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 @@ -210,6 +233,7 @@ jobs: strategy: matrix: python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + numpy: ['numpy">2"'] experimental: [false] runner: [windows-latest] continue-on-error: ${{ matrix.experimental }} diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml index 8f74fce5..5fbc3ad6 100644 --- a/conda-recipe-cf/meta.yaml +++ b/conda-recipe-cf/meta.yaml @@ -32,10 +32,12 @@ requirements: - mkl-devel - tbb-devel - numpy + - wheel >=0.41.3 run: - python - python-gil # [py>=314] - mkl-service + - {{ pin_compatible('numpy') }} - {{ pin_compatible('intel-cmplr-lib-rt') }} test: From fe35dca6e4f776c016d818cac727fccb59f62b04 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 23:22:34 -0800 Subject: [PATCH 15/22] use stdlib('c') in conda-forge meta.yaml --- conda-recipe-cf/conda_build_config.yaml | 24 ++++++++++++++++++++++++ conda-recipe-cf/meta.yaml | 11 +++++------ 2 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 conda-recipe-cf/conda_build_config.yaml diff --git a/conda-recipe-cf/conda_build_config.yaml b/conda-recipe-cf/conda_build_config.yaml new file mode 100644 index 00000000..6f302ab0 --- /dev/null +++ b/conda-recipe-cf/conda_build_config.yaml @@ -0,0 +1,24 @@ +numpy: + - '1.26.4' +c_compiler: # [linux] + - gcc # [linux] +cxx_compiler: # [linux] + - gxx # [linux] +cxx_compiler_version: # [linux] + - '14' # [linux] +c_stdlib: # [linux] + - sysroot # [linux] +c_stdlib_version: # [linux] + - '2.28' # [linux] +c_stdlib: # [win] + - vs # [win] +cxx_compiler: # [win] + - vs2022 # [win] +c_compiler: # [win] + - vs2022 # [win] +CFLAGS: + - -fno-fast-math # [linux] +CXXFLAGS: + - -fno-fast-math # [linux] +CL: + - /fp:precise # [win] diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml index 5fbc3ad6..24eace96 100644 --- a/conda-recipe-cf/meta.yaml +++ b/conda-recipe-cf/meta.yaml @@ -1,15 +1,14 @@ -{% set version = "0.4.0dev1" %} -{% set buildnumber = 0 %} - package: name: mkl_umath - version: {{ version }} + version: {{ GIT_DESCRIBE_TAG }} source: path: ../ build: - number: {{ buildnumber }} + number: {{ GIT_DESCRIBE_NUMBER }} + script_env: + - WHEELS_OUTPUT_FOLDER ignore_run_exports: - blas @@ -17,8 +16,8 @@ requirements: build: - {{ compiler('c') }} - {{ compiler('cxx') }} + - {{ stdlib('c') }} - {{ compiler('dpcpp') }} >=2024.2 # [not osx] - - sysroot_linux-64 >=2.28 # [linux] host: - meson-python >=0.13.0 - meson From b94403b0817f4e8979dce36d56269c466e29f3c9 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 4 Mar 2026 23:22:39 -0800 Subject: [PATCH 16/22] fix typo in bld.bat --- conda-recipe-cf/bld.bat | 2 +- conda-recipe/bld.bat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conda-recipe-cf/bld.bat b/conda-recipe-cf/bld.bat index d2a5956e..58178a84 100644 --- a/conda-recipe-cf/bld.bat +++ b/conda-recipe-cf/bld.bat @@ -6,7 +6,7 @@ set "CC=icx" set "CXX=icx" %PYTHON% -m build -w -n -x -if %ERRORLEVEL% neq "0" exit 1 +if %ERRORLEVEL% neq 0 exit 1 for /f %%f in ('dir /b /S .\dist') do ( %PYTHON% -m pip install %%f ^ diff --git a/conda-recipe/bld.bat b/conda-recipe/bld.bat index d2a5956e..58178a84 100644 --- a/conda-recipe/bld.bat +++ b/conda-recipe/bld.bat @@ -6,7 +6,7 @@ set "CC=icx" set "CXX=icx" %PYTHON% -m build -w -n -x -if %ERRORLEVEL% neq "0" exit 1 +if %ERRORLEVEL% neq 0 exit 1 for /f %%f in ('dir /b /S .\dist') do ( %PYTHON% -m pip install %%f ^ From 6eba727eb49f85b5c7389a3db37b3758e8340670 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 5 Mar 2026 00:09:56 -0800 Subject: [PATCH 17/22] remove intel-openmp dependency on conda-forge --- .github/workflows/conda-package-cf.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index ea27592d..488a5426 100644 --- a/.github/workflows/conda-package-cf.yml +++ b/.github/workflows/conda-package-cf.yml @@ -321,8 +321,6 @@ jobs: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}- ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}- - # add intel-openmp as an explicit dependency - # to avoid it being missed when package version is specified exactly - name: Install mkl_umath shell: cmd /C CALL {0} run: | @@ -334,10 +332,7 @@ jobs: FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO ( SET PACKAGE_VERSION=%%F ) - SET "TEST_DEPENDENCIES=pytest pytest-cov" - SET "WORKAROUND_DEPENDENCIES=intel-openmp" - SET "DEPENDENCIES=%TEST_DEPENDENCIES% %WORKAROUND_DEPENDENCIES%" - conda install -n mkl_umath_test ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% %DEPENDENCIES% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} + conda install -n mkl_umath_test ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% pytest python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} - name: Report content of test environment shell: cmd /C CALL {0} From db2a0eb0e980b257e66c870f09ec49d7f7e602c7 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 5 Mar 2026 00:10:05 -0800 Subject: [PATCH 18/22] add pip to meta.yamls --- conda-recipe-cf/meta.yaml | 1 + conda-recipe/meta.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml index 24eace96..1b458233 100644 --- a/conda-recipe-cf/meta.yaml +++ b/conda-recipe-cf/meta.yaml @@ -32,6 +32,7 @@ requirements: - tbb-devel - numpy - wheel >=0.41.3 + - pip run: - python - python-gil # [py>=314] diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 6cab0c07..b555102a 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -32,6 +32,7 @@ requirements: - tbb-devel - numpy-base - wheel >=0.41.3 + - pip run: - python - python-gil # [py>=314] From d711f765c4a48affe6068724015af75e6bc3bb4a Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 5 Mar 2026 01:21:40 -0800 Subject: [PATCH 19/22] apply actions linting to conda-package-cf --- .github/workflows/conda-package-cf.yml | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index 488a5426..6bc88849 100644 --- a/.github/workflows/conda-package-cf.yml +++ b/.github/workflows/conda-package-cf.yml @@ -56,7 +56,7 @@ jobs: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}- - name: Add conda to system path - run: echo $CONDA/bin >> $GITHUB_PATH + run: echo "$CONDA/bin" >> "$GITHUB_PATH" - name: Install conda-build run: conda install conda-build @@ -66,7 +66,7 @@ jobs: CHANNELS=(-c conda-forge --override-channels) VERSIONS=(--python "${{ matrix.python }}" --numpy "${{ matrix.numpy }}") TEST=(--no-test) - echo "CONDA_BLD=${CONDA}/conda-bld/linux-64" >> $GITHUB_ENV + echo "CONDA_BLD=${CONDA}/conda-bld/linux-64" >> "$GITHUB_ENV" conda build \ "${TEST[@]}" \ @@ -100,21 +100,21 @@ jobs: with: name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} - name: Add conda to system path - run: echo $CONDA/bin >> $GITHUB_PATH + run: echo "$CONDA/bin" >> "$GITHUB_PATH" - name: Install conda-build run: conda install conda-build - name: Create conda channel run: | - mkdir -p $GITHUB_WORKSPACE/channel/linux-64 - mv ${PACKAGE_NAME}-*.conda $GITHUB_WORKSPACE/channel/linux-64 - conda index $GITHUB_WORKSPACE/channel + mkdir -p "$GITHUB_WORKSPACE/channel/linux-64" + mv "${PACKAGE_NAME}"-*.conda "$GITHUB_WORKSPACE/channel/linux-64" + conda index "$GITHUB_WORKSPACE/channel" # Test channel - conda search $PACKAGE_NAME -c $GITHUB_WORKSPACE/channel --override-channels + conda search "$PACKAGE_NAME" -c "$GITHUB_WORKSPACE/channel" --override-channels - name: Collect dependencies run: | - CHANNELS="-c $GITHUB_WORKSPACE/channel ${{ env.CHANNELS }}" - conda create -n test_mkl_umath $PACKAGE_NAME python=${{ matrix.python }} $CHANNELS --only-deps --dry-run > lockfile + CHANNELS=(-c "$GITHUB_WORKSPACE/channel" -c "conda-forge" --override-channels) + conda create -n test_mkl_umath "$PACKAGE_NAME" "python=${{ matrix.python }}" "${CHANNELS[@]}" --only-deps --dry-run > lockfile - name: Display lockfile run: cat lockfile @@ -136,20 +136,20 @@ jobs: - name: Install mkl_umath run: | - CHANNELS="-c $GITHUB_WORKSPACE/channel ${{ env.CHANNELS }}" - conda create -n test_mkl_umath python=${{ matrix.python }} $PACKAGE_NAME pytest $CHANNELS + CHANNELS=(-c "$GITHUB_WORKSPACE/channel" -c "conda-forge" --override-channels) + conda create -n test_mkl_umath "python=${{ matrix.python }}" "$PACKAGE_NAME" pytest "${CHANNELS[@]}" # Test installed packages conda list -n test_mkl_umath - name: Smoke test run: | - source $CONDA/etc/profile.d/conda.sh + source "$CONDA/etc/profile.d/conda.sh" conda activate test_mkl_umath python -c "import mkl_umath, numpy as np; mkl_umath.use_in_numpy(); np.sin(np.linspace(0, 1, num=10**6));" - name: Run tests run: | - source $CONDA/etc/profile.d/conda.sh + source "$CONDA/etc/profile.d/conda.sh" conda activate test_mkl_umath pytest -v --pyargs ${{ env.PACKAGE_NAME }} @@ -205,7 +205,7 @@ jobs: - name: Store conda paths as envs shell: bash -l {0} run: | - echo "CONDA_BLD=$CONDA/conda-bld/win-64/" | tr "\\\\" '/' >> $GITHUB_ENV + echo "CONDA_BLD=$CONDA/conda-bld/win-64/" | tr "\\\\" '/' >> "$GITHUB_ENV" - name: Install conda build run: | From 72232cb7bd432794d813ab766ceaa630fc2259e1 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 5 Mar 2026 01:22:29 -0800 Subject: [PATCH 20/22] ignore git blame of previous commit fixing linting --- .git-blame-ignore-revs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index f58872f6..a5ec6fc8 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -5,3 +5,6 @@ # added more linters 3a3df3fae1574558973e3829368dc8a7b9c76ad9 + +# fix linting in conda-package-cf +f94f488ce98e06e5ffab1ce02ecd525b1680726c From b052459b34defc8b93ab2447b4bf318bc577609b Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 5 Mar 2026 18:33:18 -0800 Subject: [PATCH 21/22] fix race condition in meson build --- meson.build | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 23b0baa8..c2424036 100644 --- a/meson.build +++ b/meson.build @@ -111,7 +111,6 @@ src_file = generator( ) gen_loops_c = src_file.process('mkl_umath/src/mkl_umath_loops.c.src') -gen_loops_h = src_file.process('mkl_umath/src/mkl_umath_loops.h.src') gen_umath_c = custom_target( '__umath_generated', @@ -120,6 +119,14 @@ gen_umath_c = custom_target( command: [py, '@INPUT@', '-o', '@OUTPUT@'] ) +gen_loops_h = custom_target( + 'mkl_umath_loops_h', + output: ['mkl_umath_loops.h'], + input: 'mkl_umath/src/mkl_umath_loops.h.src', + command: [src_file_cli, '@INPUT@', '-o', '@OUTPUT@'], + depends: gen_umath_c +) + mkl_umath_loops = shared_library( 'mkl_umath_loops', sources: [gen_loops_c, gen_loops_h], @@ -143,7 +150,7 @@ endif # gen_loops_h is generated by custom target so must be included in sources py.extension_module( '_ufuncs', - sources: ['mkl_umath/src/ufuncsmodule.c', gen_umath_c, gen_loops_h], + sources: ['mkl_umath/src/ufuncsmodule.c', gen_loops_h], include_directories: inc_np, dependencies: [mkl_dep, tbb_dep, loops_dep], c_args: c_args + ['-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION'], From 9a6ae1c6ab6fe6b440616f2ccc6fc7af9cfdf6dc Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 5 Mar 2026 22:59:53 -0800 Subject: [PATCH 22/22] clean up windows build workflows --- .github/workflows/conda-package-cf.yml | 36 ++++++++++++++------------ .github/workflows/conda-package.yml | 34 ++++++++++++------------ 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index 6bc88849..2e080c74 100644 --- a/.github/workflows/conda-package-cf.yml +++ b/.github/workflows/conda-package-cf.yml @@ -10,6 +10,8 @@ permissions: read-all env: PACKAGE_NAME: mkl_umath + MODULE_NAME: mkl_umath + TEST_ENV_NAME: test_mkl_umath VER_SCRIPT1: "import json; f = open('ver.json', 'r'); j = json.load(f); f.close(); d = j['mkl_umath'][0];" VER_SCRIPT2: "print('='.join((d[s] for s in ('version', 'build'))))" @@ -114,7 +116,7 @@ jobs: - name: Collect dependencies run: | CHANNELS=(-c "$GITHUB_WORKSPACE/channel" -c "conda-forge" --override-channels) - conda create -n test_mkl_umath "$PACKAGE_NAME" "python=${{ matrix.python }}" "${CHANNELS[@]}" --only-deps --dry-run > lockfile + conda create -n "${{ env.TEST_ENV_NAME }}" "$PACKAGE_NAME" "python=${{ matrix.python }}" "${CHANNELS[@]}" --only-deps --dry-run > lockfile - name: Display lockfile run: cat lockfile @@ -137,21 +139,21 @@ jobs: - name: Install mkl_umath run: | CHANNELS=(-c "$GITHUB_WORKSPACE/channel" -c "conda-forge" --override-channels) - conda create -n test_mkl_umath "python=${{ matrix.python }}" "$PACKAGE_NAME" pytest "${CHANNELS[@]}" + conda create -n "${{ env.TEST_ENV_NAME }}" "python=${{ matrix.python }}" "$PACKAGE_NAME" pytest "${CHANNELS[@]}" # Test installed packages - conda list -n test_mkl_umath + conda list -n "${{ env.TEST_ENV_NAME }}" - name: Smoke test run: | source "$CONDA/etc/profile.d/conda.sh" - conda activate test_mkl_umath + conda activate "${{ env.TEST_ENV_NAME }}" python -c "import mkl_umath, numpy as np; mkl_umath.use_in_numpy(); np.sin(np.linspace(0, 1, num=10**6));" - name: Run tests run: | source "$CONDA/etc/profile.d/conda.sh" - conda activate test_mkl_umath - pytest -v --pyargs ${{ env.PACKAGE_NAME }} + conda activate "${{ env.TEST_ENV_NAME }}" + pytest -v --pyargs ${{ env.MODULE_NAME }} build_windows: runs-on: windows-latest @@ -185,9 +187,10 @@ jobs: with: miniforge-variant: Miniforge3 miniforge-version: latest - activate-environment: build + auto-activate: true + activate-environment: base channels: conda-forge - conda-remove-defaults: "true" + conda-remove-defaults: true python-version: ${{ matrix.python }} - name: Cache conda packages @@ -249,11 +252,10 @@ jobs: - uses: conda-incubator/setup-miniconda@fc2d68f6413eb2d87b895e92f8584b5b94a10167 # v3.3.0 with: - miniforge-variant: Miniforge3 miniforge-version: latest - activate-environment: mkl_umath_test channels: conda-forge - conda-remove-defaults: "true" + conda-remove-defaults: true + activate-environment: ${{ env.TEST_ENV_NAME }} python-version: ${{ matrix.python }} - name: Install conda-index @@ -303,7 +305,7 @@ jobs: FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO ( SET PACKAGE_VERSION=%%F ) - conda install -n mkl_umath_test ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} --only-deps --dry-run > lockfile + conda install -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} --only-deps --dry-run > lockfile - name: Display lockfile content shell: pwsh @@ -332,7 +334,7 @@ jobs: FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO ( SET PACKAGE_VERSION=%%F ) - conda install -n mkl_umath_test ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% pytest python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} + conda install -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% pytest python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} - name: Report content of test environment shell: cmd /C CALL {0} @@ -340,17 +342,17 @@ jobs: conda activate echo "Value of CONDA environment variable was: " %CONDA% echo "Value of CONDA_PREFIX environment variable was: " %CONDA_PREFIX% - conda info && conda list -n mkl_umath_test + conda info && conda list -n ${{ env.TEST_ENV_NAME }} - name: Smoke test shell: cmd /C CALL {0} run: | @ECHO ON - conda activate mkl_umath_test + conda activate ${{ env.TEST_ENV_NAME }} python -c "import mkl_umath, numpy as np; mkl_umath.use_in_numpy(); np.sin(np.linspace(0, 1, num=10**6));" - name: Run tests shell: cmd /C CALL {0} run: | - conda activate mkl_umath_test - python -m pytest -v -s --pyargs ${{ env.PACKAGE_NAME }} + conda activate ${{ env.TEST_ENV_NAME }} + python -m pytest -v -s --pyargs ${{ env.MODULE_NAME }} diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml index 20b6c3ce..ad6d5fb7 100644 --- a/.github/workflows/conda-package.yml +++ b/.github/workflows/conda-package.yml @@ -10,6 +10,8 @@ permissions: read-all env: PACKAGE_NAME: mkl_umath + MODULE_NAME: mkl_umath + TEST_ENV_NAME: test_mkl_umath VER_SCRIPT1: "import json; f = open('ver.json', 'r'); j = json.load(f); f.close(); d = j['mkl_umath'][0];" VER_SCRIPT2: "print('='.join((d[s] for s in ('version', 'build'))))" @@ -102,7 +104,7 @@ jobs: - name: Collect dependencies run: | CHANNELS=(-c "$GITHUB_WORKSPACE/channel" -c "https://software.repos.intel.com/python/conda" -c "conda-forge" --override-channels) - conda create -n test_mkl_umath "$PACKAGE_NAME" "python=${{ matrix.python }}" "${CHANNELS[@]}" --only-deps --dry-run > lockfile + conda create -n "${{ env.TEST_ENV_NAME }}" "$PACKAGE_NAME" "python=${{ matrix.python }}" "${CHANNELS[@]}" --only-deps --dry-run > lockfile - name: Display lockfile run: cat lockfile @@ -125,20 +127,20 @@ jobs: - name: Install mkl_umath run: | CHANNELS=(-c "$GITHUB_WORKSPACE/channel" -c "https://software.repos.intel.com/python/conda" -c "conda-forge" --override-channels) - conda create -n test_mkl_umath "python=${{ matrix.python }}" "$PACKAGE_NAME" pytest "${CHANNELS[@]}" + conda create -n "${{ env.TEST_ENV_NAME }}" "python=${{ matrix.python }}" "$PACKAGE_NAME" pytest "${CHANNELS[@]}" # Test installed packages - conda list -n test_mkl_umath + conda list -n "${{ env.TEST_ENV_NAME }}" - name: Smoke test run: | source "$CONDA/etc/profile.d/conda.sh" - conda activate test_mkl_umath + conda activate "${{ env.TEST_ENV_NAME }}" python -c "import mkl_umath, numpy as np; mkl_umath.use_in_numpy(); np.sin(np.linspace(0, 1, num=10**6));" - name: Run tests run: | source "$CONDA/etc/profile.d/conda.sh" - conda activate test_mkl_umath + conda activate "${{ env.TEST_ENV_NAME }}" pytest -v --pyargs ${{ env.PACKAGE_NAME }} build_windows: @@ -162,9 +164,10 @@ jobs: with: miniforge-variant: Miniforge3 miniforge-version: latest - activate-environment: build + auto-activate: true + activate-environment: base channels: conda-forge - conda-remove-defaults: "true" + conda-remove-defaults: true python-version: ${{ matrix.python }} - name: Cache conda packages @@ -225,11 +228,10 @@ jobs: - uses: conda-incubator/setup-miniconda@fc2d68f6413eb2d87b895e92f8584b5b94a10167 # v3.3.0 with: - miniforge-variant: Miniforge3 miniforge-version: latest - activate-environment: mkl_umath_test channels: conda-forge - conda-remove-defaults: "true" + conda-remove-defaults: true + activate-environment: ${{ env.TEST_ENV_NAME }} python-version: ${{ matrix.python }} - name: Install conda-index @@ -279,7 +281,7 @@ jobs: FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "%SCRIPT%"`) DO ( SET PACKAGE_VERSION=%%F ) - conda install -n mkl_umath_test ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} --only-deps --dry-run > lockfile + conda install -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} --only-deps --dry-run > lockfile - name: Display lockfile content shell: pwsh @@ -313,7 +315,7 @@ jobs: SET "TEST_DEPENDENCIES=pytest pytest-cov" SET "WORKAROUND_DEPENDENCIES=intel-openmp" SET "DEPENDENCIES=%TEST_DEPENDENCIES% %WORKAROUND_DEPENDENCIES%" - conda install -n mkl_umath_test ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% %DEPENDENCIES% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} + conda install -n ${{ env.TEST_ENV_NAME }} ${{ env.PACKAGE_NAME }}=%PACKAGE_VERSION% %DEPENDENCIES% python=${{ matrix.python }} -c ${{ env.workdir }}/channel ${{ env.CHANNELS }} - name: Report content of test environment shell: cmd /C CALL {0} @@ -321,17 +323,17 @@ jobs: conda activate echo "Value of CONDA environment variable was: " %CONDA% echo "Value of CONDA_PREFIX environment variable was: " %CONDA_PREFIX% - conda info && conda list -n mkl_umath_test + conda info && conda list -n ${{ env.TEST_ENV_NAME }} - name: Smoke test shell: cmd /C CALL {0} run: | @ECHO ON - conda activate mkl_umath_test + conda activate ${{ env.TEST_ENV_NAME }} python -c "import mkl_umath, numpy as np; mkl_umath.use_in_numpy(); np.sin(np.linspace(0, 1, num=10**6));" - name: Run tests shell: cmd /C CALL {0} run: | - conda activate mkl_umath_test - python -m pytest -v -s --pyargs ${{ env.PACKAGE_NAME }} + conda activate ${{ env.TEST_ENV_NAME }} + python -m pytest -v -s --pyargs ${{ env.MODULE_NAME }}