Commit f04f1c7d authored by Robert McGibbon's avatar Robert McGibbon
Browse files

Enable testing of OpenCL platform on Travis-CI

This patch creates a new build in the Travis-CI matrix that compiles and
runs the OpenCL tests using the CPU OpenCL device (AMD drivers). Because
not all of the tests can complete in the allotted 50 minutes, the ctest
invocation is changed to run them in a random order.

This also adds a new executable, TestOpenCLDeviceQuery, that prints
out information about all of the OpenCL devices on the system.
parent 1d11b995
language: python language: python
python:
- "2.7_with_system_site_packages"
- "3.4"
sudo: false
addons: addons:
apt: apt:
sources: sources:
...@@ -16,15 +12,26 @@ addons: ...@@ -16,15 +12,26 @@ addons:
- python-numpy - python-numpy
- python-scipy - python-scipy
matrix:
env: include:
matrix: - sudo: required
- OPENMM_BUILD_STATIC_LIB="OFF" python: 3.4
- OPENMM_BUILD_STATIC_LIB="ON" env: SUDO=true OPENMM_BUILD_STATIC_LIB=OFF CC=gcc CXX=g++
- sudo: false
python: 2.7_with_system_site_packages
env: SUDO=false OPENMM_BUILD_STATIC_LIB=ON CC=clang CXX=clang++
- sudo: false
python: 2.7_with_system_site_packages
env: SUDO=false OPENMM_BUILD_STATIC_LIB=OFF CC=clang CXX=clang++
- sudo: false
python: 3.4
env: SUDO=false OPENMM_BUILD_STATIC_LIB=OFF CC=gcc CXX=g++
allow_failures:
- sudo: required
before_install: before_install:
- export CC=clang - echo $SUDO
- export CXX=clang++ - if [[ "$SUDO" == "true" ]]; then sudo apt-get install -qq fglrx=2:8.960-0ubuntu1 opencl-headers; fi
- wget https://anaconda.org/anaconda/swig/3.0.2/download/linux-64/swig-3.0.2-0.tar.bz2 - wget https://anaconda.org/anaconda/swig/3.0.2/download/linux-64/swig-3.0.2-0.tar.bz2
- mkdir $HOME/swig - mkdir $HOME/swig
...@@ -33,20 +40,21 @@ before_install: ...@@ -33,20 +40,21 @@ before_install:
- export SWIG_LIB=$HOME/swig/share/swig/3.0.2 - export SWIG_LIB=$HOME/swig/share/swig/3.0.2
script: script:
- CTEST_STOP_TIME=$(python -c "from datetime import datetime, timedelta; import sys; sys.stdout.write((datetime.now() + timedelta(minutes=30)).strftime('%H:%M:%S'))")
- cmake -DCMAKE_INSTALL_PREFIX=$HOME/OpenMM -DOPENMM_BUILD_STATIC_LIB=$OPENMM_BUILD_STATIC_LIB . - cmake -DCMAKE_INSTALL_PREFIX=$HOME/OpenMM -DOPENMM_BUILD_STATIC_LIB=$OPENMM_BUILD_STATIC_LIB .
- make -j2
- make -j2 install - make -j2 install
- if [[ "$SUDO" == "true" ]]; then ./TestOpenCLDeviceQuery; fi
- make PythonInstall - make PythonInstall
- # Run the testInstallation script - # Run the testInstallation script
- python -m simtk.testInstallation - python -m simtk.testInstallation
- # run all of the tests, making sure failures at this stage don't cause travis failures - # run all of the tests, making sure failures at this stage don't cause travis failures
- ctest -j2 || true - ctest -j2 --output-on-failure --schedule-random --stop-time $CTEST_STOP_TIME || true
- # get a list of all of the failed tests into this stupid ctest format - # get a list of all of the failed tests into this stupid ctest format
- python -c "import os; fn = os.path.join('Testing', 'Temporary', 'LastTestsFailed.log'); os.path.exists(fn) or exit(0); failed = [line.split(':')[0] for line in open(fn)]; print(','.join(x+','+x for x in failed))" > FailedTests.log - python -c "import os; fn = os.path.join('Testing', 'Temporary', 'LastTestsFailed.log'); os.path.exists(fn) or exit(0); failed = [line.split(':')[0] for line in open(fn)]; print(','.join(x+','+x for x in failed))" > FailedTests.log
- # rerun all of the failed tests - # rerun all of the failed tests
- if [ -s Testing/Temporary/LastTestsFailed.log ]; then ctest -I FailedTests.log; fi; - if [ -s Testing/Temporary/LastTestsFailed.log ]; then ctest -I FailedTests.log; fi;
- # run the python tests too - # run the python tests too
- cd python/tests - cd python/tests
- # nosetests -vv --processes=-1 --process-timeout=200 - # nosetests -vv --processes=-1 --process-timeout=200
- # nosetests -vv - # nosetests -vv
- py.test -v * - py.test -v *
......
/**
* This file is adapted from vexcl's (https://github.com/ddemidov/vexcl)
* example "devlist.cpp", which is
*
* Copyright (c) 2012-2014 Denis Demidov <dennis.demidov@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <iostream>
#include <iomanip>
#include <sstream>
#include <iterator>
#include <set>
#include <algorithm>
#include <vector>
#include "OpenCLContext.h"
using namespace std;
#define SHOW_DEVPROP(name) \
cout << " " << left << setw(32) << #name << " = " \
<< d.getInfo< name >() << endl
int main() {
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
cout << "OpenCL devices:" << endl << endl;
for (int j = 0; j < platforms.size(); j++) {
vector<cl::Device> devices;
platforms[j].getDevices(CL_DEVICE_TYPE_ALL, &devices);
for (int i = 0; i < devices.size(); i++) {
cl::Device d = devices[i];
cout << "OpenCLPlatformIndex " << j << ", OpenCLDeviceIndex " << i << ": \"" << d.getInfo<CL_DEVICE_NAME>()
<< "\"" << endl << " " << left << setw(32) << "CL_PLATFORM_NAME" << " = "
<< cl::Platform(d.getInfo<CL_DEVICE_PLATFORM>()).getInfo<CL_PLATFORM_NAME>()
<< endl
<< " " << left << setw(32) << "CL_PLATFORM_VENDOR" << " = "
<< platforms[j].getInfo<CL_PLATFORM_VENDOR>()
<< endl;
SHOW_DEVPROP(CL_DEVICE_VENDOR);
SHOW_DEVPROP(CL_DEVICE_VERSION);
cout << " " << left << setw(32) << "CL_DEVICE_TYPE" << " = ";
if (d.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_CPU) {
cout << "CL_DEVICE_TYPE_CPU" << endl;
} else if (d.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_GPU) {
cout << "CL_DEVICE_TYPE_GPU" << endl;
} else if (d.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_ACCELERATOR) {
cout << "CL_DEVICE_TYPE_ACCELERATOR" << endl;
} else {
cout << "Unknown" << endl;
}
SHOW_DEVPROP(CL_DEVICE_MAX_COMPUTE_UNITS);
cout << " " << left << setw(32) << "CL_DEVICE_MAX_WORK_ITEM_SIZES" << " = [";
for (int k = 0; k < d.getInfo<CL_DEVICE_MAX_WORK_ITEM_SIZES>().size(); k++) {
cout << d.getInfo<CL_DEVICE_MAX_WORK_ITEM_SIZES>()[k];
if (k < d.getInfo<CL_DEVICE_MAX_WORK_ITEM_SIZES>().size() - 1)
cout << ", ";
}
cout << "]" << endl;
SHOW_DEVPROP(CL_DEVICE_HOST_UNIFIED_MEMORY);
SHOW_DEVPROP(CL_DEVICE_GLOBAL_MEM_SIZE);
SHOW_DEVPROP(CL_DEVICE_LOCAL_MEM_SIZE);
SHOW_DEVPROP(CL_DEVICE_MAX_MEM_ALLOC_SIZE);
SHOW_DEVPROP(CL_DEVICE_ADDRESS_BITS);
SHOW_DEVPROP(CL_DEVICE_MAX_CLOCK_FREQUENCY);
int processingElementsPerComputeUnit;
if (d.getInfo<CL_DEVICE_TYPE>() != CL_DEVICE_TYPE_GPU) {
processingElementsPerComputeUnit = 1;
} else if (d.getInfo<CL_DEVICE_EXTENSIONS>().find("cl_nv_device_attribute_query") != string::npos) {
cl_uint computeCapabilityMajor;
#ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
clGetDeviceInfo(d(), CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, sizeof(cl_uint), &computeCapabilityMajor, NULL);
processingElementsPerComputeUnit = (computeCapabilityMajor < 2 ? 8 : 32);
#endif
} else if (d.getInfo<CL_DEVICE_EXTENSIONS>().find("cl_amd_device_attribute_query") != string::npos) {
#ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD
try {
processingElementsPerComputeUnit = d.getInfo<CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD>() *
d.getInfo<CL_DEVICE_SIMD_WIDTH_AMD>() *
d.getInfo<CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD>();
} catch (cl::Error err) {}
#endif
}
cout << " processingElementsPerComputeUnit" << " = " << processingElementsPerComputeUnit << endl;
int speed = devices[i].getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>()*processingElementsPerComputeUnit*d.getInfo<CL_DEVICE_MAX_CLOCK_FREQUENCY>();
cout << " estimatedSpeed = " << speed << endl;
cout << " " << left << setw(32) << "CL_DEVICE_EXTENSIONS" << " = ";
istringstream iss(d.getInfo<CL_DEVICE_EXTENSIONS>());
set<string> extensions;
extensions.insert(istream_iterator<string>(iss), istream_iterator<string>());
size_t w = 40;
for (set<string>::iterator s = extensions.begin(); s != extensions.end(); ++s) {
w += s->length() + 1;
if (w > 80) {
cout << endl << setw(w = 8) << "";
w += s->length() + 1;
}
cout << *s << " ";
}
cout << endl << endl;
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment