FindISPC.cmake 4.75 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
find_package(Common)


SET(ISPC_VERSION_REQUIRED "1.8.2")

IF (NOT ISPC_EXECUTABLE)
  #  if ($ENV{ISPC})
  #  FIND_PROGRAM(ISPC_EXECUTABLE NAME ispc PATH $ENV{ISPC} DOC "Path to the ISPC executable.")
  # endif()
  FIND_PROGRAM(ISPC_EXECUTABLE ispc DOC "Path to the ISPC executable.")
  IF (NOT ISPC_EXECUTABLE)
    MESSAGE(STATUS  "Intel SPMD Compiler (ISPC) is not found.")
  ELSE()
    MESSAGE(STATUS "Found Intel SPMD Compiler (ISPC): ${ISPC_EXECUTABLE}")
    set(ISPC_FOUND True)
  ENDIF()
ENDIF()


if (NOT ISPC_EXECUTABLE)
  set(ISPC_FOUND False)
else(NOT ISPC_EXECUTABLE)
  set(ISPC_FOUND True)
  IF(NOT ISPC_VERSION)
    EXECUTE_PROCESS(COMMAND ${ISPC_EXECUTABLE} --version OUTPUT_VARIABLE ISPC_OUTPUT)
    STRING(REGEX MATCH " ([0-9]+[.][0-9]+[.][0-9]+)(dev|knl|ptx)? " DUMMY "${ISPC_OUTPUT}")
    SET(ISPC_VERSION ${CMAKE_MATCH_1})

    #IF (ISPC_VERSION VERSION_LESS ISPC_VERSION_REQUIRED)
      #      MESSAGE(FATAL_ERROR "Need at least version ${ISPC_VERSION_REQUIRED} of Intel SPMD Compiler (ISPC).")
      #    ENDIF()
    MESSAGE(STATUS "Found ISPC version ${ISPC_VERSION}")

    SET(ISPC_VERSION ${ISPC_VERSION} CACHE STRING "ISPC Version")
    MARK_AS_ADVANCED(ISPC_VERSION)
    MARK_AS_ADVANCED(ISPC_EXECUTABLE)
  ENDIF()

  function(ispc_compile _obj_list)
    get_sources_and_options(sources compile_flags "COMPILE_FLAGS" ${ARGN})

    set(__XEON__ True)
    
    IF (__XEON__)
      SET (ISPC_TARGET_EXT ${CMAKE_CXX_OUTPUT_EXTENSION})
    ELSE()
      SET (ISPC_TARGET_EXT .cpp)
      SET (ISPC_ADDITIONAL_ARGS ${ISPC_ADDITIONAL_ARGS} --opt=force-aligned-memory)
    ENDIF()
    
    IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
      SET(ISPC_ARCHITECTURE "x86-64")
    ELSE()
      SET(ISPC_ARCHITECTURE "x86")
    ENDIF()
    
    SET(ISPC_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${ISPC_TARGET_DIR})
    
    IF(ISPC_INCLUDE_DIR)
      STRING(REPLACE ";" ";-I;" ISPC_INCLUDE_DIR_PARMS "${ISPC_INCLUDE_DIR}")
      SET(ISPC_INCLUDE_DIR_PARMS "-I" ${ISPC_INCLUDE_DIR_PARMS})
    ENDIF()

    set(___XEON___ True)
    IF (__XEON__)
      STRING(REPLACE ";" "," ISPC_TARGET_ARGS "${ISPC_TARGETS}")
    ELSE()
      #    SET(ISPC_TARGET_ARGS generic-16)
      #SET(ISPC_ADDITIONAL_ARGS ${ISPC_ADDITIONAL_ARGS} --emit-c++ -D__XEON_PHI__ --c++-include-file=${ISPC_DIR}/examples/intrinsics/knc.h)j
    ENDIF()
    
    SET(ISPC_OBJECTS ${${_obj_list}})

    foreach (src ${sources})
      get_filename_component(fname ${src} NAME_WE)
      get_filename_component(dir   ${src} PATH)
      
      IF("${dir}" STREQUAL "")
        SET(outdir ${ISPC_TARGET_DIR})
      ELSE("${dir}" STREQUAL "")
        SET(outdir ${ISPC_TARGET_DIR}/${dir})
      ENDIF("${dir}" STREQUAL "")
      SET(outdirh ${ISPC_TARGET_DIR})

      SET(deps "")
      IF (EXISTS ${outdir}/${fname}.dev.idep)
        FILE(READ ${outdir}/${fname}.dev.idep contents)
        STRING(REPLACE " " ";"     contents "${contents}")
        STRING(REPLACE ";" "\\\\;" contents "${contents}")
        STRING(REPLACE "\n" ";"    contents "${contents}")
        FOREACH(dep ${contents})
          IF (EXISTS ${dep})
            SET(deps ${deps} ${dep})
          ENDIF (EXISTS ${dep})
        ENDFOREACH(dep ${contents})
      ENDIF ()

      SET(results "${outdir}/${fname}.dev${ISPC_TARGET_EXT}")

      # if we have multiple targets add additional object files
      IF (__XEON__)
        LIST(LENGTH ISPC_TARGETS NUM_TARGETS)
        IF (NUM_TARGETS GREATER 1)
          FOREACH(target ${ISPC_TARGETS})
            SET(results ${results} "${outdir}/${fname}.dev_${target}${ISPC_TARGET_EXT}")
          ENDFOREACH()
        ENDIF()
      ENDIF()

      IF (WIN32)
        SET(ISPC_ADDITIONAL_ARGS ${ISPC_ADDITIONAL_ARGS} --dllexport)
      ELSE()
        SET(ISPC_ADDITIONAL_ARGS ${ISPC_ADDITIONAL_ARGS} --pic)
      ENDIF()

      separate_arguments(compile_flags)

      ADD_CUSTOM_COMMAND(
        OUTPUT ${results} ${outdirh}/${fname}_ispc.h
        COMMAND ${CMAKE_COMMAND} -E make_directory ${outdir}
        COMMAND ${ISPC_EXECUTABLE}
        ${compile_flags}
        -I ${CMAKE_CURRENT_SOURCE_DIR}
        ${ISPC_INCLUDE_DIR_PARMS}
        --arch=${ISPC_ARCHITECTURE}
        #      --addressing=${EMBREE_ISPC_ADDRESSING}
        #      -O3
        #--target=${ISPC_TARGET_ARGS}
        #--woff
        # --opt=fast-math
        ${ISPC_ADDITIONAL_ARGS}
        -h ${outdirh}/${fname}_ispc.h
        -MMM  ${outdir}/${fname}.dev.idep
        -o ${outdir}/${fname}.dev${ISPC_TARGET_EXT}
        ${CMAKE_CURRENT_SOURCE_DIR}/${src}
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${deps}
        COMMENT "Building ISPC object ${outdir}/${fname}.dev${ISPC_TARGET_EXT}"
      )

      SET(ISPC_OBJECTS ${ISPC_OBJECTS} ${results})
    endforeach()

    set(${_obj_list} ${ISPC_OBJECTS} PARENT_SCOPE)
  endfunction()
endif(NOT ISPC_EXECUTABLE)