Commit 1d22d002 authored by Eric Anholt's avatar Eric Anholt

Merge remote-tracking branch 'blaz/opencl-request-v2'

This introduces OpenCL testing to piglit under tests/all_cl.tests.
parents 460fc1e6 7a37e626
......@@ -19,6 +19,7 @@ find_package(X11)
option(BUILD_GLES1_TESTS "Build tests for OpenGL ES1" OFF)
option(BUILD_GLES2_TESTS "Build tests for OpenGL ES2" OFF)
option(BUILD_CL_TESTS "Build tests for OpenCL" OFF)
option(USE_WAFFLE "Use Waffle in place of GLUT" OFF)
if(USE_WAFFLE)
......@@ -36,6 +37,10 @@ if(BUILD_GLES2_TESTS AND NOT USE_WAFFLE)
message(FATAL_ERROR "Option BUILD_GLES2_TESTS requires USE_WAFFLE")
endif(BUILD_GLES2_TESTS AND NOT USE_WAFFLE)
if(BUILD_CL_TESTS)
find_package(OpenCL REQUIRED)
endif(BUILD_CL_TESTS)
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
add_definitions(-DPIGLIT_HAS_X11)
option(BUILD_GLX_TESTS "Build tests that require GLX" ON)
......
......@@ -12,10 +12,11 @@ Piglit
1. About
--------
Piglit is a collection of automated tests for OpenGL implementations.
Piglit is a collection of automated tests for OpenGL and OpenCL
implementations.
The goal of Piglit is to help improve the quality of open source
OpenGL drivers by providing developers with a simple means to
OpenGL and OpenCL drivers by providing developers with a simple means to
perform regression tests.
The original tests have been taken from
......@@ -259,6 +260,9 @@ sanity.tests
all.tests
This suite contains all tests.
all_cl.tests
This suite contains all OpenCL tests.
quick.tests
Run all tests, but cut down significantly on their runtime
(and thus on the number of problems they can find).
......
# Copyright © 2012 Blaž Tomažič <blaz.tomazic@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 (including the next
# paragraph) 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.
# This module defines the following variables:
#
# OPENCL_FOUND
# True if OpenCL is installed.
#
# OPENCL_INCLUDE_PATH
#
# OPENCL_opencl_LIBRARY
# Path to OpenCL's library.
find_path(OPENCL_INCLUDE_PATH CL/opencl.h)
find_library(OPENCL_opencl_LIBRARY OpenCL)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenCL
DEFAULT_MSG
OPENCL_opencl_LIBRARY OPENCL_INCLUDE_PATH
)
......@@ -29,7 +29,7 @@ function(piglit_include_target_api)
# Verify that the value of `piglit_target_api` is valid.
set(valid_api FALSE)
foreach(api "gl" "gles1" "gles2" "no_api")
foreach(api "gl" "gles1" "gles2" "cl" "no_api")
if(piglit_target_api STREQUAL ${api})
set(valid_api TRUE)
break()
......
......@@ -32,3 +32,7 @@ endif(BUILD_GLES1_TESTS)
if(BUILD_GLES2_TESTS)
add_subdirectory(gles2)
endif(BUILD_GLES2_TESTS)
if(BUILD_CL_TESTS)
add_subdirectory(cl)
endif(BUILD_CL_TESTS)
set(piglit_target_api "cl")
add_definitions(
-DUSE_OPENCL
)
add_subdirectory(${piglit_SOURCE_DIR}/tests
${piglit_BINARY_DIR}/target_api/${piglit_target_api}/tests
)
......@@ -25,6 +25,10 @@ IF(OPENGL_egl_LIBRARY)
add_subdirectory (egl)
ENDIF(OPENGL_egl_LIBRARY)
IF(BUILD_CL_TESTS)
add_subdirectory (cl)
ENDIF(BUILD_CL_TESTS)
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
add_subdirectory (mesa)
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# All OpenCL tests that come with piglit, using default settings
import os
from framework.core import *
from framework.exectest import *
######
# Helper functions
def add_plain_test(group, name, args):
group[name] = PlainExecTest(args)
def add_concurrent_test(group, name, args):
test = PlainExecTest(args)
test.runConcurrent = true;
group[name] = PlainExecTest(args)
def add_plain_program_tester_test(group, name, filename):
add_plain_test(group, name, ['cl-program-tester', 'tests/cl/program/'+filename])
######
# Collecting all tests
profile = TestProfile()
custom = Group()
api = Group()
program = Group()
profile.tests['Custom'] = custom
profile.tests['API'] = api
profile.tests['Program'] = program
######
# Tests
# Custom
add_plain_test(custom, 'Run simple kernel', ['cl-custom-run-simple-kernel'])
# API
# Platform
add_plain_test(api, 'clGetPlatformIDs', ['cl-api-get-platform-ids'])
add_plain_test(api, 'clGetPlatformInfo', ['cl-api-get-platform-info'])
# Device
add_plain_test(api, 'clGetDeviceIDs', ['cl-api-get-device-ids'])
add_plain_test(api, 'clGetDeviceInfo', ['cl-api-get-device-info'])
# Context
add_plain_test(api, 'clCreateContext', ['cl-api-create-context'])
add_plain_test(api, 'clCreateContextFromType', ['cl-api-create-context-from-type'])
add_plain_test(api, 'clGetContextInfo', ['cl-api-get-context-info'])
add_plain_test(api, 'clRetainContext and clReleaseContext', ['cl-api-retain_release-context'])
# Command Queues
add_plain_test(api, 'clCreateCommandQueue', ['cl-api-create-command-queue'])
add_plain_test(api, 'clRetainComandQueue and clReleaseCommandQueue', ['cl-api-retain_release-command-queue'])
add_plain_test(api, 'clGetCommandQueueInfo', ['cl-api-get-command-queue-info'])
# Memory objects
add_plain_test(api, 'clCreateBuffer', ['cl-api-create-buffer'])
add_plain_test(api, 'clEnqueueReadBuffer and clEnqueueWriteBuffer', ['cl-api-enqueue-read_write-buffer'])
add_plain_test(api, 'clGetMemObjectInfo', ['cl-api-get-mem-object-info'])
add_plain_test(api, 'clGetImageInfo', ['cl-api-get-image-info'])
add_plain_test(api, 'clRetainMemObject and clReleaseMemObject', ['cl-api-retain_release-mem-object'])
# Program
add_plain_test(api, 'clCreateProgramWithSource', ['cl-api-create-program-with-source'])
add_plain_test(api, 'clBuildProgram', ['cl-api-build-program'])
add_plain_test(api, 'clCreateKernelsInProgram', ['cl-api-create-kernels-in-program'])
add_plain_test(api, 'clGetProgramInfo', ['cl-api-get-program-info'])
add_plain_test(api, 'clGetProgramBuildInfo', ['cl-api-get-program-build-info'])
add_plain_test(api, 'clRetainProgram and clReleaseProgram', ['cl-api-retain_release-program'])
add_plain_test(api, 'clUnloadCompiler', ['cl-api-unload-compiler'])
# Kernel
add_plain_test(api, 'clCreateKernel', ['cl-api-create-kernel'])
add_plain_test(api, 'clCreateKernelsInProgram', ['cl-api-create-kernels-in-program'])
add_plain_test(api, 'clGetKernelInfo', ['cl-api-get-kernel-info'])
add_plain_test(api, 'clGetKernelWorkGroupInfo', ['cl-api-get-kernel-work-group-info'])
add_plain_test(api, 'clRetainKernel and clReleaseKernel', ['cl-api-retain_release-kernel'])
add_plain_test(api, 'clSetKernelArg', ['cl-api-set-kernel-arg'])
# Event
add_plain_test(api, 'clGetEventInfo', ['cl-api-get-event-info'])
add_plain_test(api, 'clRetainEvent and clReleaseEvent', ['cl-api-retain_release-event'])
# Program
add_plain_test(program, 'Run kernel with max work item sizes', ['cl-program-max-work-item-sizes'])
# Program tester
program_build = Group()
program_build_fail = Group()
program_execute = Group()
program["Build"] = program_build
program["Build"]["Fail"] = program_build_fail
program["Execute"] = program_execute
# Build
add_plain_program_tester_test(program_build, 'Scalar data types', 'build/scalar-data-types.cl')
add_plain_program_tester_test(program_build, 'Scalar data type half', 'build/scalar-data-type-half.cl')
add_plain_program_tester_test(program_build, 'Vector data types', 'build/vector-data-types.cl')
add_plain_program_tester_test(program_build, 'Other data types', 'build/other-data-types.cl')
add_plain_program_tester_test(program_build, 'Scalar operators', 'build/scalar-operators.cl')
add_plain_program_tester_test(program_build, 'Vector operators', 'build/vector-operators.cl')
add_plain_program_tester_test(program_build, 'Scalar and vector operators', 'build/scalar-and-vector-operators.cl')
add_plain_program_tester_test(program_build_fail, 'Increment operator on float', 'build/fail/increment-float.cl')
add_plain_program_tester_test(program_build_fail, 'Add different size vector', 'build/fail/add-different-size-vector.cl')
# Execute
add_plain_program_tester_test(program_execute, 'Scalar arithmetic char', 'execute/scalar-arithmetic-char.cl')
add_plain_program_tester_test(program_execute, 'Scalar arithmetic float', 'execute/scalar-arithmetic-float.cl')
add_plain_program_tester_test(program_execute, 'Scalar arithmetic int', 'execute/scalar-arithmetic-int.cl')
add_plain_program_tester_test(program_execute, 'Scalar arithmetic long', 'execute/scalar-arithmetic-long.cl')
add_plain_program_tester_test(program_execute, 'Scalar arithmetic short', 'execute/scalar-arithmetic-short.cl')
add_plain_program_tester_test(program_execute, 'Scalar arithmetic uchar', 'execute/scalar-arithmetic-uchar.cl')
add_plain_program_tester_test(program_execute, 'Scalar arithmetic uint', 'execute/scalar-arithmetic-uint.cl')
add_plain_program_tester_test(program_execute, 'Scalar arithmetic ulong', 'execute/scalar-arithmetic-ulong.cl')
add_plain_program_tester_test(program_execute, 'Scalar arithmetic ushort', 'execute/scalar-arithmetic-ushort.cl')
add_plain_program_tester_test(program_execute, 'Vector arithmetic int4', 'execute/vector-arithmetic-int4.program_test')
add_plain_program_tester_test(program_execute, 'Vector arithmetic float4', 'execute/vector-arithmetic-float4.program_test')
add_plain_program_tester_test(program_execute, 'Vector load int4', 'execute/vector-load-int4.cl')
add_plain_program_tester_test(program_execute, 'Scalar bitwise op int', 'execute/scalar-bitwise-int.cl')
add_plain_program_tester_test(program_execute, 'Scalar comparison char', 'execute/scalar-comparison-char.cl')
add_plain_program_tester_test(program_execute, 'Scalar comparison float', 'execute/scalar-comparison-float.cl')
add_plain_program_tester_test(program_execute, 'Scalar comparison int', 'execute/scalar-comparison-int.cl')
add_plain_program_tester_test(program_execute, 'Scalar comparison long', 'execute/scalar-comparison-long.cl')
add_plain_program_tester_test(program_execute, 'Scalar comparison short', 'execute/scalar-comparison-short.cl')
add_plain_program_tester_test(program_execute, 'Scalar comparison uchar', 'execute/scalar-comparison-uchar.cl')
add_plain_program_tester_test(program_execute, 'Scalar comparison uint', 'execute/scalar-comparison-uint.cl')
add_plain_program_tester_test(program_execute, 'Scalar comparison ulong', 'execute/scalar-comparison-ulong.cl')
add_plain_program_tester_test(program_execute, 'Scalar comparison ushort', 'execute/scalar-comparison-ushort.cl')
add_plain_program_tester_test(program_execute, 'Scalar logical op float', 'execute/scalar-logical-float.cl')
add_plain_program_tester_test(program_execute, 'Scalar logical op int', 'execute/scalar-logical-int.cl')
add_plain_program_tester_test(program_execute, 'Sizeof operator', 'execute/sizeof.cl')
add_plain_program_tester_test(program_execute, 'Comma operator', 'execute/comma.cl')
add_plain_program_tester_test(program_execute, 'Reference and dereference operators', 'execute/reference.cl')
add_plain_program_tester_test(program_execute, 'get_global_id', 'execute/get-global-id.cl')
add_plain_program_tester_test(program_execute, 'For loop', 'execute/for-loop.cl')
include_directories(
${OPENCL_INCLUDE_PATH}
${piglit_SOURCE_DIR}/tests/util
)
link_libraries (
piglitutil_${piglit_target_api}
${OPENCL_opencl_LIBRARY}
)
function(piglit_cl_add_test)
add_executable(${ARGV})
endfunction(piglit_cl_add_test)
function(piglit_cl_add_custom_test name)
list(REMOVE_AT ARGV 0)
piglit_cl_add_test(
cl-custom-${name}
${ARGV}
)
endfunction(piglit_cl_add_custom_test)
function(piglit_cl_add_api_test name)
list(REMOVE_AT ARGV 0)
piglit_cl_add_test(
cl-api-${name}
${ARGV}
)
endfunction(piglit_cl_add_api_test)
function(piglit_cl_add_program_test name)
list(REMOVE_AT ARGV 0)
piglit_cl_add_test(
cl-program-${name}
${ARGV}
)
endfunction(piglit_cl_add_program_test)
add_subdirectory (custom)
add_subdirectory (api)
add_subdirectory (program)
OpenCL testing framework
------------------------
1. About
2. Test types
3. How to run tests
4. How to write tests
1. About
--------
This framework is used to write OpenCL tests for Piglit framework.
The framework supports creating tests to run once or per each platform (if
cl_khr_icd is supported, else only one platform is tested) or per each
device. Each test can be limited to a particular group of platforms or
devices.
There are different test types which can be used to write a test. These
test types automate checking for different implementation functionality
(OpenCL version, extensions, filter by platform name,...) and creating
objects (context creation, program creation and building, source code
loading, buffer creation and buffer data initialization,...).
2. Test types
-------------
Currently there are three different types of tests:
* API tests:
These type of tests are meant for testing the API functions.
Documentation is located at tests/cl/doc_api.c.
* Program tests:
These type of tests are meant for testing compilation of OpenCL C
programs and kernel execution. These tests can be normal C/C++ programs
or special files that are parsed by program-tester
(bin/cl-program-tester). This program takes in an ini-like file
(test.program_test) or an OpenCL source code (test.cl) with a special
comment. The binary programs (test.bin) can be referenced from
program_test files.
Documentation is located at tests/cl/doc_program.c,
test/cl/doc_program.cl and test/cl/doc_program.program_test.
* Custom tests:
These type of tests are for tests that don't fit well in any other test
type.
Documentation is located at tests/cl/doc_custom.c.
3. How to run tests
-------------------
All compilable tests are compiled to the bin/ folder. Each test has a
prefix applied to it, depending on its type:
* API: cl-api-
* Program: cl-program-
* Custom: cl-custom-
The OpenCL C and program_test tests are parsed and run by program-tester
that is located at bin/cl-program-tester.
Each test can be run independently or they can all be run by Piglit as a
test set. The test set is located at tests/all_cl.tests.
Each test accepts the following environment variables:
* PIGLIT_CL_PLATFORM: Only run test on platforms whose platform name
begins with PIGLIT_CL_PLATFORM. (This variable
is accepted only when the test is run per platform
or per device)
* PIGLIT_CL_DEVICE: Only run tests on devices whose device name begins
with PIGLIT_CL_DEVICE. (This variable is accepted only
when the test is run per device)
* PIGLIT_CL_VERSION: Test against OpenCL version PIGLIT_CL_VERSION. This
variable is a normal OprnCL versioning number
(example: 1.1).
The same variables are accepted as program arguments:
* -platform name: Same as PIGLIT_CL_PLATFORM.
* -device name: Same as PIGLIT_CL_DEVICE.
* -version ver: Same as PIGLIT_CL_VERSION.
4. How to write tests
---------------------
Tests should be created in appropriate folder in cl/tests:
* api/: API tests
* program/: Program tests
* program/build/: Program-tester compilation tests
* program/build/fail/: Program-tester compilation tests that should fail
* program/execute: Program-tester kernel execution tests
Templates for the different types of tests and documentation for them is
located at tests/cl/doc_* and tests/cl/template_*.
To cover the widest range of OpenCL versions with one test, each compiled
test is passed an env->version variable which contains a version number
against which the test should test. Also the PIGLIT_CL_VERSION macro
present in piglit-util-cl.h contains a version number against which Piglit
was compiled. Both numbers are multiples of 10 of OpenCL version (1.1 -> 11).
The program tests run by program-tester (bin/cl-program-tester) are compiled
with a macro __OPENCL_C_VERSION__ which tells against which version the
source will be compiled. To comply with OpenCL spec this version number is a
multiple of 100 of OpenCL C version (1.1 -> 110).
All new tests should be added to an appropriate group in tests/all_cl.tests.
# Basic
piglit_cl_add_api_test (get-platform-ids get-platform-ids.c)
piglit_cl_add_api_test (get-platform-info get-platform-info.c)
piglit_cl_add_api_test (get-device-ids get-device-ids.c)
piglit_cl_add_api_test (get-device-info get-device-info.c)
piglit_cl_add_api_test (create-context create-context.c)
piglit_cl_add_api_test (create-context-from-type create-context-from-type.c)
piglit_cl_add_api_test (get-context-info get-context-info.c)
piglit_cl_add_api_test (retain_release-context retain_release-context.c)
# Command queues
piglit_cl_add_api_test (create-command-queue create-command-queue.c)
piglit_cl_add_api_test (get-command-queue-info get-command-queue-info.c)
piglit_cl_add_api_test (retain_release-command-queue retain_release-command-queue.c)
# Memory objects
piglit_cl_add_api_test (create-buffer create-buffer.c)
piglit_cl_add_api_test (enqueue-read_write-buffer enqueue-read_write-buffer.c)
piglit_cl_add_api_test (retain_release-mem-object retain_release-mem-object.c)
piglit_cl_add_api_test (get-mem-object-info get-mem-object-info.c)
piglit_cl_add_api_test (get-image-info get-image-info.c)
# Programs
piglit_cl_add_api_test (create-program-with-source create-program-with-source.c)
piglit_cl_add_api_test (retain_release-program retain_release-program.c)
piglit_cl_add_api_test (build-program build-program.c)
piglit_cl_add_api_test (unload-compiler unload-compiler.c)
piglit_cl_add_api_test (get-program-info get-program-info.c)
piglit_cl_add_api_test (get-program-build-info get-program-build-info.c)
# Kernels
piglit_cl_add_api_test (create-kernel create-kernel.c)
piglit_cl_add_api_test (create-kernels-in-program create-kernels-in-program.c)
piglit_cl_add_api_test (set-kernel-arg set-kernel-arg.c)
piglit_cl_add_api_test (retain_release-kernel retain_release-kernel.c)
piglit_cl_add_api_test (get-kernel-info get-kernel-info.c)
piglit_cl_add_api_test (get-kernel-work-group-info get-kernel-work-group-info.c)
# Events
piglit_cl_add_api_test (retain_release-event retain_release-event.c)
piglit_cl_add_api_test (get-event-info get-event-info.c)
piglit_include_target_api()
/*
* Copyright © 2012 Blaž Tomažič <blaz.tomazic@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 (including the next
* paragraph) 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.
*/
/**
* @file build-program.c
*
* Test API function:
*
* cl_int clBuildProgram (cl_program program,
* cl_uint num_devices,
* const cl_device_id *device_list,
* const char *options,
* void (CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
* void *user_data)
*/
#include "piglit-framework-cl-api.h"
PIGLIT_CL_API_TEST_CONFIG_BEGIN
config.name = "clBuildProgram";
config.version_min = 10;
config.run_per_platform = true;
config.create_context = true;
PIGLIT_CL_API_TEST_CONFIG_END
const char* strings[] = {
"void dummy_function() {}",
"kernel void dummy_kernel() { dummy_function(); }",
};
const char* invalid_strings[] = {
"kernel void dummy_kernel {}", // missing brackets intentionaly
};
static bool
test(cl_program program,
cl_uint num_devices,
const cl_device_id *device_list,
const char *options,
void (CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
void *user_data,
cl_int expected_error,
enum piglit_result* result,
const char* test_str) {
cl_int errNo;
errNo = clBuildProgram(program,
num_devices,
device_list,
options,
pfn_notify,
user_data);
if(!piglit_cl_check_error(errNo, expected_error)) {
fprintf(stderr, "Failed (error code: %s): %s.\n",
piglit_cl_get_error_name(errNo), test_str);
piglit_merge_result(result, PIGLIT_FAIL);
return false;
}
return true;
}
enum piglit_result
piglit_cl_test(const int argc,
const char** argv,
const struct piglit_cl_api_test_config* config,
const struct piglit_cl_api_test_env* env)
{
enum piglit_result result = PIGLIT_PASS;
int i;
cl_int errNo;
cl_program program;
cl_program temp_program;
cl_kernel kernel;
/*** Normal usage ***/
/* Create program */
/* with binary */
//TODO
/* with source */
program = clCreateProgramWithSource(env->context->cl_ctx,
2,
strings,
NULL,
&errNo);
if(!piglit_cl_check_error(errNo, CL_SUCCESS)) {
fprintf(stderr,
"Failed (error code: %s): Create program with source.\n",
piglit_cl_get_error_name(errNo));
return PIGLIT_FAIL;
}
test(program, env->context->num_devices, env->context->device_ids, "",
NULL, NULL,
CL_SUCCESS, &result, "Build program");
// TODO: test callback
// TODO: test build options
/*** Errors ***/
/*
* CL_INVALID_PROGRAM if program is not a valid program object.
*/
test(NULL, env->context->num_devices, env->context->device_ids, "",
NULL, NULL,
CL_INVALID_PROGRAM, &result,
"Trigger CL_INVALID_PROGRAM if program is not a valid program object");
/*
* CL_INVALID_VALUE if device_list is NULL and num_devices is greater than
* zero, or if device_list is not NULL and num_devices is zero.
*/
test(program, 1, NULL, "", NULL, NULL,
CL_INVALID_VALUE, &result,
"Trigger CL_INVALID_VALUE if device_list is NULL and num_devices is greater than zero");
test(program, 0, env->context->device_ids, "", NULL, NULL,
CL_INVALID_VALUE, &result,
"Trigger CL_INVALID_VALUE if device_list is not NULL and num_devices is zero"