vtk-m/CMake/VTKmMacros.cmake
Kenneth Moreland 0581a83aa2 Directly call python when executing expander.py
On Unix-based systems, you can directly execute a script and the system
will automatically run it through its associated interpreter. However,
on Windows this does not work. You just get an error about the script,
which is just a text file, being an invalid executable.

This was an issue when running pyexpander. Now, Python is called
directly for pyexpander.
2016-06-16 10:36:20 -06:00

609 lines
22 KiB
CMake
Executable File

##============================================================================
## Copyright (c) Kitware, Inc.
## All rights reserved.
## See LICENSE.txt for details.
## This software is distributed WITHOUT ANY WARRANTY; without even
## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
## PURPOSE. See the above copyright notice for more information.
##
## Copyright 2014 Sandia Corporation.
## Copyright 2014 UT-Battelle, LLC.
## Copyright 2014 Los Alamos National Security.
##
## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
## the U.S. Government retains certain rights in this software.
##
## Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
## Laboratory (LANL), the U.S. Government retains certain rights in
## this software.
##============================================================================
include(CMakeParseArguments)
# Utility to build a kit name from the current directory.
function(vtkm_get_kit_name kitvar)
# Will this always work? It should if ${CMAKE_CURRENT_SOURCE_DIR} is
# built from ${VTKm_SOURCE_DIR}.
string(REPLACE "${VTKm_SOURCE_DIR}/" "" dir_prefix ${CMAKE_CURRENT_SOURCE_DIR})
string(REPLACE "/" "_" kit "${dir_prefix}")
set(${kitvar} "${kit}" PARENT_SCOPE)
# Optional second argument to get dir_prefix.
if (${ARGC} GREATER 1)
set(${ARGV1} "${dir_prefix}" PARENT_SCOPE)
endif (${ARGC} GREATER 1)
endfunction(vtkm_get_kit_name)
#Utility to setup nvcc flags so that we properly work around issues inside FindCUDA.
#if we are generating cu files need to setup four things.
#1. Explicitly set the cuda device adapter as a define this is currently
# done as a work around since the cuda executable ignores compile
# definitions
#2. Set BOOST_SP_DISABLE_THREADS to disable threading warnings
#3. Disable unused function warnings
# the FindCUDA module and helper methods don't read target level
# properties so we have to modify CUDA_NVCC_FLAGS instead of using
# target and source level COMPILE_FLAGS and COMPILE_DEFINITIONS
#4. Set the compile option /bigobj when using VisualStudio generators.
# While we have specified this as target compile flag, those aren't
# currently loooked at by FindCUDA, so we have to manually add it ourselves
function(vtkm_setup_nvcc_flags old_flags )
set(${old_flags} ${CUDA_NVCC_FLAGS} PARENT_SCOPE)
set(new_flags ${CUDA_NVCC_FLAGS})
list(APPEND new_flags "-DVTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_CUDA")
list(APPEND new_flags "-DBOOST_SP_DISABLE_THREADS")
list(APPEND new_flags "-w")
if(MSVC)
list(APPEND new_flags "--compiler-options;/bigobj")
endif()
set(CUDA_NVCC_FLAGS ${new_flags} PARENT_SCOPE)
endfunction(vtkm_setup_nvcc_flags)
#Utility to set MSVC only COMPILE_DEFINITIONS and COMPILE_FLAGS needed to
#reduce number of warnings and compile issues with Visual Studio
function(vtkm_setup_msvc_properties target )
#disable MSVC CRT and SCL warnings as they recommend using non standard
#c++ extensions
set_property(TARGET ${target}
APPEND PROPERTY COMPILE_DEFINITIONS
"_SCL_SECURE_NO_WARNINGS"
"_CRT_SECURE_NO_WARNINGS"
)
#enable large object support so we can have 2^32 addressable sections
set_property(TARGET ${target}
APPEND PROPERTY COMPILE_FLAGS
"/bigobj"
)
endfunction(vtkm_setup_msvc_properties)
# Builds a source file and an executable that does nothing other than
# compile the given header files.
function(vtkm_add_header_build_test name dir_prefix use_cuda)
set(hfiles ${ARGN})
if (use_cuda)
set(suffix ".cu")
else (use_cuda)
set(suffix ".cxx")
endif (use_cuda)
set(cxxfiles)
foreach (header ${ARGN})
get_source_file_property(cant_be_tested ${header} VTKm_CANT_BE_HEADER_TESTED)
if( NOT cant_be_tested )
string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}" "" header "${header}")
get_filename_component(headername ${header} NAME_WE)
set(src ${CMAKE_CURRENT_BINARY_DIR}/TB_${headername}${suffix})
configure_file(${VTKm_SOURCE_DIR}/CMake/TestBuild.cxx.in ${src} @ONLY)
list(APPEND cxxfiles ${src})
endif()
endforeach (header)
#only attempt to add a test build executable if we have any headers to
#test. this might not happen when everything depends on thrust.
list(LENGTH cxxfiles cxxfiles_len)
if (use_cuda AND ${cxxfiles_len} GREATER 0)
cuda_add_library(TestBuild_${name} ${cxxfiles} ${hfiles})
elseif (${cxxfiles_len} GREATER 0)
add_library(TestBuild_${name} ${cxxfiles} ${hfiles})
if(VTKm_EXTRA_COMPILER_WARNINGS)
set_property(TARGET ${test_prog}
APPEND PROPERTY COMPILE_FLAGS
${CMAKE_CXX_FLAGS_WARN_EXTRA}
)
endif(VTKm_EXTRA_COMPILER_WARNINGS)
endif ()
set_source_files_properties(${hfiles}
PROPERTIES HEADER_FILE_ONLY TRUE
)
endfunction(vtkm_add_header_build_test)
function(vtkm_install_headers dir_prefix)
set(hfiles ${ARGN})
install(FILES ${hfiles}
DESTINATION ${VTKm_INSTALL_INCLUDE_DIR}/${dir_prefix}
)
endfunction(vtkm_install_headers)
function(vtkm_install_template_sources)
vtkm_get_kit_name(name dir_prefix)
set(hfiles ${ARGN})
vtkm_install_headers("${dir_prefix}" ${hfiles})
# CMake does not add installed files as project files, and template sources
# are not declared as source files anywhere, add a fake target here to let
# an IDE know that these sources exist.
add_custom_target(${name}_template_srcs SOURCES ${hfiles})
endfunction(vtkm_install_template_sources)
# Declare a list of headers that require thrust to be enabled
# for them to header tested. In cases of thrust version 1.5 or less
# we have to make sure openMP is enabled, otherwise we are okay
function(vtkm_requires_thrust_to_test)
#determine the state of thrust and testing
set(cant_be_tested FALSE)
if(NOT VTKm_ENABLE_THRUST)
#mark as not valid
set(cant_be_tested TRUE)
elseif(NOT VTKm_ENABLE_OPENMP)
#mark also as not valid
set(cant_be_tested TRUE)
endif()
foreach(header ${ARGN})
#set a property on the file that marks if we can header test it
set_source_files_properties( ${header}
PROPERTIES VTKm_CANT_BE_HEADER_TESTED ${cant_be_tested} )
endforeach(header)
endfunction(vtkm_requires_thrust_to_test)
# Declare a list of header files. Will make sure the header files get
# compiled and show up in an IDE.
function(vtkm_declare_headers)
set(options CUDA)
set(oneValueArgs TESTABLE)
set(multiValueArgs)
cmake_parse_arguments(VTKm_DH "${options}"
"${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)
#The testable keyword allows the caller to turn off the header testing,
#mainly used so that backends can be installed even when they can't be
#built on the machine.
#Since this is an optional property not setting it means you do want testing
if(NOT DEFINED VTKm_DH_TESTABLE)
set(VTKm_DH_TESTABLE ON)
endif()
set(hfiles ${VTKm_DH_UNPARSED_ARGUMENTS})
vtkm_get_kit_name(name dir_prefix)
#only do header testing if enable testing is turned on
if (VTKm_ENABLE_TESTING AND VTKm_DH_TESTABLE)
vtkm_add_header_build_test(
"${name}" "${dir_prefix}" "${VTKm_DH_CUDA}" ${hfiles})
endif()
#always install headers
vtkm_install_headers("${dir_prefix}" ${hfiles})
endfunction(vtkm_declare_headers)
# Declare a list of worklet files.
function(vtkm_declare_worklets)
# Currently worklets are just really header files.
vtkm_declare_headers(${ARGN})
endfunction(vtkm_declare_worklets)
function(vtkm_pyexpander_generated_file generated_file_name)
# If pyexpander is available, add targets to build and check
if(PYEXPANDER_FOUND AND PYTHONINTERP_FOUND)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${generated_file_name}.checked
COMMAND ${CMAKE_COMMAND}
-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
-DPYEXPANDER_COMMAND=${PYEXPANDER_COMMAND}
-DSOURCE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${generated_file_name}
-DGENERATED_FILE=${CMAKE_CURRENT_BINARY_DIR}/${generated_file_name}
-P ${CMAKE_SOURCE_DIR}/CMake/VTKmCheckPyexpander.cmake
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${generated_file_name}.in
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${generated_file_name}
COMMENT "Checking validity of ${generated_file_name}"
)
add_custom_target(check_${generated_file_name} ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${generated_file_name}.checked
)
endif()
endfunction(vtkm_pyexpander_generated_file)
# Declare unit tests, which should be in the same directory as a kit
# (package, module, whatever you call it). Usage:
#
# vtkm_unit_tests(
# SOURCES <source_list>
# LIBRARIES <dependent_library_list>
# )
function(vtkm_unit_tests)
set(options CUDA)
set(oneValueArgs)
set(multiValueArgs SOURCES LIBRARIES)
cmake_parse_arguments(VTKm_UT
"${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)
#set up what we possibly need to link too.
list(APPEND VTKm_UT_LIBRARIES ${VTKm_LIBRARIES})
#set up storage for the include dirs
set(VTKm_UT_INCLUDE_DIRS )
if(VTKm_ENABLE_OPENGL_INTEROP)
list(APPEND VTKm_UT_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIR} )
list(APPEND VTKm_UT_LIBRARIES ${OPENGL_LIBRARIES} ${GLEW_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} )
endif()
if(VTKm_ENABLE_OPENGL_TESTS)
list(APPEND VTKm_UT_INCLUDE_DIRS ${GLUT_INCLUDE_DIR} )
list(APPEND VTKm_UT_LIBRARIES ${GLUT_LIBRARIES} )
endif()
if (VTKm_ENABLE_TESTING)
vtkm_get_kit_name(kit)
#we use UnitTests_ so that it is an unique key to exclude from coverage
set(test_prog UnitTests_${kit})
create_test_sourcelist(TestSources ${test_prog}.cxx ${VTKm_UT_SOURCES})
#determine the timeout for all the tests based on the backend. CUDA tests
#generally require more time because of kernel generation.
set(timeout 180)
if (VTKm_UT_CUDA)
set(timeout 1500)
endif()
if (VTKm_UT_CUDA)
vtkm_setup_nvcc_flags( old_nvcc_flags )
cuda_add_executable(${test_prog} ${TestSources})
set(CUDA_NVCC_FLAGS ${old_nvcc_flags})
else (VTKm_UT_CUDA)
add_executable(${test_prog} ${TestSources})
endif (VTKm_UT_CUDA)
#do it as a property value so we don't pollute the include_directories
#for any other targets
set_property(TARGET ${test_prog} APPEND PROPERTY
INCLUDE_DIRECTORIES ${VTKm_UT_INCLUDE_DIRS} )
target_link_libraries(${test_prog} ${VTKm_UT_LIBRARIES})
target_compile_options(${test_prog} PRIVATE ${VTKm_COMPILE_OPTIONS})
if(MSVC)
vtkm_setup_msvc_properties(${test_prog})
endif()
if(VTKm_EXTRA_COMPILER_WARNINGS)
set_property(TARGET ${test_prog}
APPEND PROPERTY COMPILE_FLAGS
${CMAKE_CXX_FLAGS_WARN_EXTRA}
)
endif(VTKm_EXTRA_COMPILER_WARNINGS)
foreach (test ${VTKm_UT_SOURCES})
get_filename_component(tname ${test} NAME_WE)
add_test(NAME ${tname}
COMMAND ${test_prog} ${tname}
)
set_tests_properties("${tname}" PROPERTIES TIMEOUT ${timeout})
endforeach (test)
endif (VTKm_ENABLE_TESTING)
endfunction(vtkm_unit_tests)
# Save the worklets to test with each device adapter
# Usage:
#
# vtkm_save_worklet_unit_tests( sources )
#
# notes: will save the sources absolute path as the
# vtkm_source_worklet_unit_tests global property
function(vtkm_save_worklet_unit_tests )
#create the test driver when we are called, since
#the test driver expect the test files to be in the same
#directory as the test driver
create_test_sourcelist(test_sources WorkletTestDriver.cxx ${ARGN})
#store the absolute path for the test drive and all the test
#files
set(driver ${CMAKE_CURRENT_BINARY_DIR}/WorkletTestDriver.cxx)
set(cxx_sources)
set(cu_sources)
#we need to store the absolute source for the file so that
#we can properly compile it into the test driver. At
#the same time we want to configure each file into the build
#directory as a .cu file so that we can compile it with cuda
#if needed
foreach(fname ${ARGN})
set(absPath)
get_filename_component(absPath ${fname} ABSOLUTE)
get_filename_component(file_name_only ${fname} NAME_WE)
set(cuda_file_name "${CMAKE_CURRENT_BINARY_DIR}/${file_name_only}.cu")
configure_file("${absPath}"
"${cuda_file_name}"
COPYONLY)
list(APPEND cxx_sources ${absPath})
list(APPEND cu_sources ${cuda_file_name})
endforeach()
#we create a property that holds all the worklets to test,
#but don't actually attempt to create a unit test with the yet.
#That is done by each device adapter
set_property( GLOBAL APPEND
PROPERTY vtkm_worklet_unit_tests_sources ${cxx_sources})
set_property( GLOBAL APPEND
PROPERTY vtkm_worklet_unit_tests_cu_sources ${cu_sources})
set_property( GLOBAL APPEND
PROPERTY vtkm_worklet_unit_tests_drivers ${driver})
endfunction(vtkm_save_worklet_unit_tests)
# Call each worklet test for the given device adapter
# Usage:
#
# vtkm_worklet_unit_tests( device_adapter )
#
# notes: will look for the vtkm_source_worklet_unit_tests global
# property to find what are the worklet unit tests that need to be
# compiled for the give device adapter
function(vtkm_worklet_unit_tests device_adapter)
set(unit_test_srcs)
get_property(unit_test_srcs GLOBAL
PROPERTY vtkm_worklet_unit_tests_sources )
set(unit_test_drivers)
get_property(unit_test_drivers GLOBAL
PROPERTY vtkm_worklet_unit_tests_drivers )
#detect if we are generating a .cu files
set(is_cuda FALSE)
if("${device_adapter}" STREQUAL "VTKM_DEVICE_ADAPTER_CUDA")
set(is_cuda TRUE)
endif()
#determine the timeout for all the tests based on the backend. The first CUDA
#worklet test requires way more time because of the overhead to allow the
#driver to convert the kernel code from virtual arch to actual arch.
#
set(timeout 180)
if(is_cuda)
set(timeout 1500)
endif()
if(VTKm_ENABLE_TESTING)
string(REPLACE "VTKM_DEVICE_ADAPTER_" "" device_type ${device_adapter})
vtkm_get_kit_name(kit)
#inject the device adapter into the test program name so each one is unique
set(test_prog WorkletTests_${device_type})
if(is_cuda)
get_property(unit_test_srcs GLOBAL PROPERTY vtkm_worklet_unit_tests_cu_sources )
vtkm_setup_nvcc_flags( old_nvcc_flags )
cuda_add_executable(${test_prog} ${unit_test_drivers} ${unit_test_srcs})
set(CUDA_NVCC_FLAGS ${old_nvcc_flags} )
else()
add_executable(${test_prog} ${unit_test_drivers} ${unit_test_srcs})
target_link_libraries(${test_prog} ${VTKm_LIBRARIES})
endif()
#add the specific compile options for this executable
target_compile_options(${test_prog} PRIVATE ${VTKm_COMPILE_OPTIONS})
#add a test for each worklet test file. We will inject the device
#adapter type into the test name so that it is easier to see what
#exact device a test is failing on.
foreach (test ${unit_test_srcs})
get_filename_component(tname ${test} NAME_WE)
add_test(NAME "${tname}${device_type}"
COMMAND ${test_prog} ${tname}
)
set_tests_properties("${tname}${device_type}" PROPERTIES TIMEOUT ${timeout})
endforeach (test)
if(MSVC)
vtkm_setup_msvc_properties(${test_prog})
endif()
#increase warning level if needed, we are going to skip cuda here
#to remove all the false positive unused function warnings that cuda
#generates
if(VTKm_EXTRA_COMPILER_WARNINGS)
set_property(TARGET ${test_prog}
APPEND PROPERTY COMPILE_FLAGS ${CMAKE_CXX_FLAGS_WARN_EXTRA} )
endif()
#set the device adapter on the executable
set_property(TARGET ${test_prog}
APPEND
PROPERTY COMPILE_DEFINITIONS "VTKM_DEVICE_ADAPTER=${device_adapter}" )
endif()
endfunction(vtkm_worklet_unit_tests)
# Save the benchmarks to run with each device adapter
# This is based on vtkm_save_worklet_unit_tests
# Usage:
#
# vtkm_save_benchmarks( <sources> [HEADERS <headers>] )
#
#
# Each benchmark source file needs to implement main(int agrc, char *argv[])
#
# notes: will save the sources absolute path as the
# vtkm_benchmarks_sources global property
function(vtkm_save_benchmarks)
#store the absolute path for all the test files
set(cxx_sources)
set(cu_sources)
cmake_parse_arguments(save_benchmarks "" "" "HEADERS" ${ARGN})
#we need to store the absolute source for the file so that
#we can properly compile it into the benchmark driver. At
#the same time we want to configure each file into the build
#directory as a .cu file so that we can compile it with cuda
#if needed
foreach(fname ${save_benchmarks_UNPARSED_ARGUMENTS})
set(absPath)
get_filename_component(absPath ${fname} ABSOLUTE)
get_filename_component(file_name_only ${fname} NAME_WE)
set(cuda_file_name "${CMAKE_CURRENT_BINARY_DIR}/${file_name_only}.cu")
configure_file("${absPath}"
"${cuda_file_name}"
COPYONLY)
list(APPEND cxx_sources ${absPath})
list(APPEND cu_sources ${cuda_file_name})
endforeach()
#we create a property that holds all the worklets to test,
#but don't actually attempt to create a unit test with the yet.
#That is done by each device adapter
set_property( GLOBAL APPEND
PROPERTY vtkm_benchmarks_sources ${cxx_sources})
set_property( GLOBAL APPEND
PROPERTY vtkm_benchmarks_cu_sources ${cu_sources})
set_property( GLOBAL APPEND
PROPERTY vtkm_benchmarks_headers ${save_benchmarks_HEADERS})
endfunction(vtkm_save_benchmarks)
# Call each benchmark for the given device adapter
# Usage:
#
# vtkm_benchmark( device_adapter )
#
# notes: will look for the vtkm_benchmarks_sources global
# property to find what are the benchmarks that need to be
# compiled for the give device adapter
function(vtkm_benchmarks device_adapter)
set(benchmark_srcs)
get_property(benchmark_srcs GLOBAL
PROPERTY vtkm_benchmarks_sources )
set(benchmark_headers)
get_property(benchmark_headers GLOBAL
PROPERTY vtkm_benchmarks_headers )
#detect if we are generating a .cu files
set(is_cuda FALSE)
set(old_nvcc_flags ${CUDA_NVCC_FLAGS})
if("${device_adapter}" STREQUAL "VTKM_DEVICE_ADAPTER_CUDA")
set(is_cuda TRUE)
endif()
if(VTKm_ENABLE_BENCHMARKS AND VTKm_ENABLE_TESTING)
string(REPLACE "VTKM_DEVICE_ADAPTER_" "" device_type ${device_adapter})
if(is_cuda)
vtkm_setup_nvcc_flags( old_nvcc_flags )
get_property(benchmark_srcs GLOBAL PROPERTY vtkm_benchmarks_cu_sources )
endif()
foreach( file ${benchmark_srcs})
#inject the device adapter into the benchmark program name so each one is unique
get_filename_component(benchmark_prog ${file} NAME_WE)
set(benchmark_prog "${benchmark_prog}_${device_type}")
if(is_cuda)
cuda_add_executable(${benchmark_prog} ${file} ${benchmark_headers})
else()
add_executable(${benchmark_prog} ${file} ${benchmark_headers})
endif()
set_source_files_properties(${benchmark_headers}
PROPERTIES HEADER_FILE_ONLY TRUE)
target_link_libraries(${benchmark_prog} ${VTKm_LIBRARIES})
if(MSVC)
vtkm_setup_msvc_properties(${benchmark_prog})
endif()
#add the specific compile options for this executable
target_compile_options(${benchmark_prog} PRIVATE ${VTKm_COMPILE_OPTIONS})
#increase warning level if needed, we are going to skip cuda here
#to remove all the false positive unused function warnings that cuda
#generates
if(VTKm_EXTRA_COMPILER_WARNINGS)
set_property(TARGET ${benchmark_prog}
APPEND PROPERTY COMPILE_FLAGS ${CMAKE_CXX_FLAGS_WARN_EXTRA} )
endif()
#set the device adapter on the executable
set_property(TARGET ${benchmark_prog}
APPEND
PROPERTY COMPILE_DEFINITIONS "VTKM_DEVICE_ADAPTER=${device_adapter}" )
endforeach()
if(is_cuda)
set(CUDA_NVCC_FLAGS ${old_nvcc_flags})
endif()
endif()
endfunction(vtkm_benchmarks)
# The Thrust project is not as careful as the VTKm project in avoiding warnings
# on shadow variables and unused arguments. With a real GCC compiler, you
# can disable these warnings inline, but with something like nvcc, those
# pragmas cause errors. Thus, this macro will disable the compiler warnings.
macro(vtkm_disable_troublesome_thrust_warnings)
vtkm_disable_troublesome_thrust_warnings_var(CMAKE_CXX_FLAGS_DEBUG)
vtkm_disable_troublesome_thrust_warnings_var(CMAKE_CXX_FLAGS_MINSIZEREL)
vtkm_disable_troublesome_thrust_warnings_var(CMAKE_CXX_FLAGS_RELEASE)
vtkm_disable_troublesome_thrust_warnings_var(CMAKE_CXX_FLAGS_RELWITHDEBINFO)
endmacro(vtkm_disable_troublesome_thrust_warnings)
macro(vtkm_disable_troublesome_thrust_warnings_var flags_var)
set(old_flags "${${flags_var}}")
string(REPLACE "-Wshadow" "" new_flags "${old_flags}")
string(REPLACE "-Wunused-parameter" "" new_flags "${new_flags}")
string(REPLACE "-Wunused" "" new_flags "${new_flags}")
string(REPLACE "-Wextra" "" new_flags "${new_flags}")
string(REPLACE "-Wall" "" new_flags "${new_flags}")
set(${flags_var} "${new_flags}")
endmacro(vtkm_disable_troublesome_thrust_warnings_var)
# Set up configuration for a given device.
macro(vtkm_configure_device device)
string(TOUPPER "${device}" device_uppercase)
set(VTKm_ENABLE_${device_uppercase} ON)
include("UseVTKm${device}")
if(NOT VTKm_${device}_FOUND)
if ("${ARGV1}" STREQUAL "REQUIRED")
message(SEND_ERROR "Could not configure for using VTKm with ${device}")
else()
message(STATUS "Could not configure for using VTKm with ${device}")
endif()
endif()
endmacro(vtkm_configure_device)