-
-
Notifications
You must be signed in to change notification settings - Fork 10.9k
ENH: enable OpenBLAS on windows. #9645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
37878bf
917652a
67a175b
06b5318
0957a1f
bcc5d1d
41407a2
e149d29
167ca98
84fdfb3
66029c7
79c476e
448bb82
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,195 @@ | ||
skip_tags: true | ||
clone_depth: 1 | ||
# As config was originally based on an example by Olivier Grisel. Thanks! | ||
# https://github.com/ogrisel/python-appveyor-demo/blob/master/appveyor.yml | ||
clone_depth: 50 | ||
|
||
os: Visual Studio 2015 | ||
# No reason for us to restrict the number concurrent jobs | ||
max_jobs: 100 | ||
|
||
cache: | ||
- '%LOCALAPPDATA%\pip\Cache' | ||
|
||
environment: | ||
global: | ||
MINGW_32: C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin | ||
MINGW_64: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin | ||
OPENBLAS_32: https://3f23b170c54c2533c070-1c8a9b3114517dc5fe17b7c3f8c63a43.ssl.cf2.rackcdn.com/openblas-5f998ef_gcc7_1_0_win32.zip | ||
OPENBLAS_64: https://3f23b170c54c2533c070-1c8a9b3114517dc5fe17b7c3f8c63a43.ssl.cf2.rackcdn.com/openblas-5f998ef_gcc7_1_0_win64.zip | ||
APPVEYOR_SAVE_CACHE_ON_ERROR: true | ||
APPVEYOR_SKIP_FINALIZE_ON_EXIT: true | ||
TEST_TIMEOUT: 1000 | ||
|
||
matrix: | ||
- PY_MAJOR_VER: 2 | ||
PYTHON_ARCH: "x86" | ||
- PY_MAJOR_VER: 3 | ||
PYTHON_ARCH: "x86_64" | ||
- PY_MAJOR_VER: 3 | ||
PYTHON_ARCH: "x86" | ||
- PYTHON: C:\Python36 | ||
PYTHON_VERSION: 3.6 | ||
PYTHON_ARCH: 32 | ||
TEST_MODE: fast | ||
|
||
build_script: | ||
# If there's a newer build queued for the same PR, cancel this one | ||
- PYTHON: C:\Python27-x64 | ||
PYTHON_VERSION: 2.7 | ||
PYTHON_ARCH: 64 | ||
TEST_MODE: fast | ||
|
||
- PYTHON: C:\Python34-x64 | ||
PYTHON_VERSION: 3.4 | ||
PYTHON_ARCH: 64 | ||
TEST_MODE: fast | ||
|
||
- PYTHON: C:\Python36-x64 | ||
PYTHON_VERSION: 3.6 | ||
PYTHON_ARCH: 64 | ||
TEST_MODE: full | ||
|
||
- PYTHON: C:\Python27 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if the tag builds are actually needed for Numpy. The production wheels are built by a different CI config, this one is used only for integration testing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think they're needed but they could be used to compare differences between the released wheels and the wheels used for testing. A major advantage of this appveyor configuration is that you can actually download the built wheels and inspect them yourself. |
||
PYTHON_VERSION: 2.7 | ||
PYTHON_ARCH: 32 | ||
SKIP_NOTAG: true | ||
TEST_MODE: full | ||
|
||
- PYTHON: C:\Python34 | ||
PYTHON_VERSION: 3.4 | ||
PYTHON_ARCH: 32 | ||
SKIP_NOTAG: true | ||
TEST_MODE: full | ||
|
||
- PYTHON: C:\Python35-x64 | ||
PYTHON_VERSION: 3.5 | ||
PYTHON_ARCH: 64 | ||
SKIP_NOTAG: true | ||
TEST_MODE: full | ||
|
||
- PYTHON: C:\Python35 | ||
PYTHON_VERSION: 3.5 | ||
PYTHON_ARCH: 32 | ||
SKIP_NOTAG: true | ||
TEST_MODE: full | ||
|
||
init: | ||
- "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%" | ||
- "ECHO \"%APPVEYOR_SCHEDULED_BUILD%\"" | ||
# If there is a newer build queued for the same PR, cancel this one. | ||
# The AppVeyor 'rollout builds' option is supposed to serve the same | ||
# purpose but it is problematic because it tends to cancel builds pushed | ||
# directly to master instead of just PR builds (or the converse). | ||
# credits: JuliaLang developers. | ||
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` | ||
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` | ||
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` | ||
throw "There are newer queued builds for this pull request, failing early." } | ||
- ps: Start-FileDownload "https://repo.continuum.io/miniconda/Miniconda$env:PY_MAJOR_VER-latest-Windows-$env:PYTHON_ARCH.exe" C:\Miniconda.exe; echo "Finished downloading miniconda" | ||
- cmd: C:\Miniconda.exe /S /D=C:\Py | ||
- SET PATH=C:\Py;C:\Py\Scripts;C:\Py\Library\bin;%PATH% | ||
- conda config --set always_yes yes | ||
- conda update conda | ||
- conda install cython nose pytz | ||
- pip install . -vvv | ||
Write-Host "There are newer queued builds for this pull request, skipping build." | ||
Exit-AppveyorBuild | ||
} | ||
- ps: | | ||
If (($env:SKIP_NOTAG -eq "true") -and ($env:APPVEYOR_REPO_TAG -ne "true")) { | ||
Write-Host "Skipping build, not at a tag." | ||
Exit-AppveyorBuild | ||
} | ||
|
||
install: | ||
# Show size of cache | ||
- C:\cygwin\bin\du -hs "%LOCALAPPDATA%\pip\Cache" | ||
# Prepend newly installed Python to the PATH of this build (this cannot be | ||
# done from inside the powershell script as it would require to restart | ||
# the parent CMD process). | ||
- SET PATH=%PYTHON%;%PYTHON%\Scripts;%PATH% | ||
|
||
# Check that we have the expected version and architecture for Python | ||
- python --version | ||
- >- | ||
%CMD_IN_ENV% | ||
python -c "import sys,platform,struct; | ||
print(sys.platform, platform.machine(), struct.calcsize('P') * 8, )" | ||
|
||
# Install "openblas.a" to PYTHON\lib | ||
# Library provided by Matthew Brett at https://github.com/matthew-brett/build-openblas | ||
- ps: | | ||
$PYTHON_ARCH = $env:PYTHON_ARCH | ||
$PYTHON = $env:PYTHON | ||
If ($PYTHON_ARCH -eq 32) { | ||
$OPENBLAS = $env:OPENBLAS_32 | ||
} Else { | ||
$OPENBLAS = $env:OPENBLAS_64 | ||
} | ||
$clnt = new-object System.Net.WebClient | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A comment here or above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually don't know the repo but matthew is in charge of these builds. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I updated the comment above the |
||
$file = "$(New-TemporaryFile).zip" | ||
$tmpdir = New-TemporaryFile | %{ rm $_; mkdir $_ } | ||
$destination = "$PYTHON\lib\openblas.a" | ||
|
||
echo $file | ||
echo $tmpdir | ||
echo $OPENBLAS | ||
|
||
$clnt.DownloadFile($OPENBLAS,$file) | ||
Get-FileHash $file | Format-List | ||
|
||
Expand-Archive $file $tmpdir | ||
|
||
rm $tmpdir\$PYTHON_ARCH\lib\*.dll.a | ||
$lib = ls $tmpdir\$PYTHON_ARCH\lib\*.a | ForEach { ls $_ } | Select-Object -first 1 | ||
echo $lib | ||
|
||
cp $lib $destination | ||
ls $destination | ||
|
||
# Upgrade to the latest pip. | ||
- '%CMD_IN_ENV% python -m pip install -U pip setuptools wheel' | ||
|
||
# Install the numpy test dependencies. | ||
- '%CMD_IN_ENV% pip install -U --timeout 5 --retries 2 -r tools/ci/appveyor/requirements.txt' | ||
|
||
build_script: | ||
# Here, we add MinGW to the path to be able to link an OpenBLAS.dll | ||
# We then use the import library from the DLL to compile with MSVC | ||
- ps: | | ||
$PYTHON_ARCH = $env:PYTHON_ARCH | ||
If ($PYTHON_ARCH -eq 32) { | ||
$MINGW = $env:MINGW_32 | ||
} Else { | ||
$MINGW = $env:MINGW_64 | ||
} | ||
$env:Path += ";$MINGW" | ||
$env:NPY_NUM_BUILD_JOBS = "4" | ||
mkdir dist | ||
pip wheel -v -v -v --wheel-dir=dist . | ||
|
||
# For each wheel that pip has placed in the "dist" directory | ||
# First, upload the wheel to the "artifacts" tab and then | ||
# install the wheel. If we have only built numpy (as is the case here), | ||
# then there will be one wheel to install. | ||
|
||
# This method is more representative of what will be distributed, | ||
# because it actually tests what the built wheels will be rather than | ||
# what 'setup.py install' will do and at it uploads the wheels so that | ||
# they can be inspected. | ||
|
||
ls dist -r | Foreach-Object { | ||
appveyor PushArtifact $_.FullName | ||
pip install $_.FullName | ||
} | ||
|
||
test_script: | ||
- python runtests.py -v -n | ||
|
||
after_build: | ||
# Remove old or huge cache files to hopefully not exceed the 1GB cache limit. | ||
# | ||
# If the cache limit is reached, the cache will not be updated (of not even | ||
# created in the first run). So this is a trade of between keeping the cache | ||
# current and having a cache at all. | ||
# NB: This is done only `on_success` since the cache in uploaded only on | ||
# success anyway. | ||
- C:\cygwin\bin\find "%LOCALAPPDATA%\pip" -type f -mtime +360 -delete | ||
- C:\cygwin\bin\find "%LOCALAPPDATA%\pip" -type f -size +10M -delete | ||
- C:\cygwin\bin\find "%LOCALAPPDATA%\pip" -empty -delete | ||
# Show size of cache | ||
- C:\cygwin\bin\du -hs "%LOCALAPPDATA%\pip\Cache" | ||
|
||
on_finish: | ||
# We can get a nice display of test results in the "test" tab with py.test | ||
# For now, this does nothing. | ||
- ps: | | ||
If (Test-Path .\junit-results.xml) { | ||
(new-object net.webclient).UploadFile( | ||
"https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", | ||
(Resolve-Path .\junit-results.xml) | ||
) | ||
} | ||
$LastExitCode = 0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -68,7 +68,7 @@ def have_compiler(): | |
try: | ||
if not compiler.initialized: | ||
compiler.initialize() # MSVC is different | ||
except DistutilsError: | ||
except (DistutilsError, ValueError): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW this is because MSVC 2008 is a crappy compiler. |
||
return False | ||
cmd = [compiler.cc] | ||
try: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -267,15 +267,18 @@ def test_error_message(self): | |
try: | ||
self._assert_func(np.array([1, 2]), np.matrix([1, 2])) | ||
except AssertionError as e: | ||
self.assertEqual( | ||
str(e), | ||
"\nArrays are not equal\n\n" | ||
"(shapes (2,), (1, 2) mismatch)\n" | ||
" x: array([1, 2])\n" | ||
" y: [repr failed for <matrix>: The truth value of an array " | ||
"with more than one element is ambiguous. Use a.any() or " | ||
"a.all()]") | ||
|
||
msg = str(e) | ||
msg2 = msg.replace("shapes (2L,), (1L, 2L)", "shapes (2,), (1, 2)") | ||
msg_reference = "\nArrays are not equal\n\n" \ | ||
"(shapes (2,), (1, 2) mismatch)\n" \ | ||
" x: array([1, 2])\n" \ | ||
" y: [repr failed for <matrix>: The truth value of an array " \ | ||
"with more than one element is ambiguous. Use a.any() or " \ | ||
"a.all()]" | ||
try: | ||
self.assertEqual(msg, msg_reference) | ||
except AssertionError: | ||
self.assertEqual(msg2, msg_reference) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The try: except is not needed. You can make it simpler via |
||
|
||
class TestArrayAlmostEqual(_GenericTest, unittest.TestCase): | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
cython | ||
nose | ||
pytest-timeout | ||
pytest-xdist | ||
pytest-env | ||
pytest-faulthandler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still want to test MSVC as well, it needs to stay working. So instead of removing it all, I suggest to use a build matrix with a mix of the two build configs (without increasing the total number of builds).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which MSVC are you concerned about? This configuration should test 2008, 2010, and 2015. The "os" has nothing to do with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ralf - I'm guessing you mean a lapack-lite build, without OpenBLAS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I didn't mean lapack-lite, that's okay to only test on Linux I think. The
install
andbuild_script
part here explicitly addMINGW
to the path and in the whole file there are only references to Cygwin and MinGW. So if MSVC is still being used, it's very much non-obvious (plus it's unclear what the purpose of the MinGW stuff is).So either something is wrong (like MSVC being dropped) or this needs a lot of comments explaining what is going on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MinGW is used to compile the OpenBLAS library. MSVC is used to compile everything else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, all the compilers are installed in the appveyor VM regardless of this setting, and Python distutils generally finds MSVC based on registry entries rather than PATH.
If present, MSVC is used by default over mingw C compilers, even if the latter is on PATH.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's my understanding too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pv @matthew-brett not sure if you're arguing against including more documentation or not. My comment is not particular to the line
os: Visual Studio 2015
. There's a lot of opaque stuff in this PR that simply needs explaining.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I'm just explaining why it works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, more documentation would be good.
I hate to be annoying, but I have previously done the same work in the windows-wheel-builder repo - here's a PR : numpy/windows-wheel-builder#3 in case it's helpful.