Added a helper function for setting the L1 kernel defaults.
authorHank Anderson <hank.p.anderson@gmail.com>
Wed, 18 Feb 2015 03:36:23 +0000 (21:36 -0600)
committerHank Anderson <hank.p.anderson@gmail.com>
Wed, 18 Feb 2015 03:36:23 +0000 (21:36 -0600)
Added loop to build objects with different KERNEL defines.

cmake/kernel.cmake [new file with mode: 0644]
cmake/utils.cmake
driver/level2/CMakeLists.txt
kernel/CMakeLists.txt

diff --git a/cmake/kernel.cmake b/cmake/kernel.cmake
new file mode 100644 (file)
index 0000000..211da22
--- /dev/null
@@ -0,0 +1,110 @@
+# helper functions for the kernel CMakeLists.txt\r
+\r
+\r
+# Set the default filenames for L1 objects. Most of these will be overriden by the appropriate KERNEL file.\r
+macro(SetDefaultL1)\r
+  set(SAMAXKERNEL amax.S)\r
+  set(DAMAXKERNEL amax.S)\r
+  set(QAMAXKERNEL amax.S)\r
+  set(CAMAXKERNEL zamax.S)\r
+  set(ZAMAXKERNEL zamax.S)\r
+  set(XAMAXKERNEL zamax.S)\r
+  set(SAMINKERNEL amin.S)\r
+  set(DAMINKERNEL amin.S)\r
+  set(QAMINKERNEL amin.S)\r
+  set(CAMINKERNEL zamin.S)\r
+  set(ZAMINKERNEL zamin.S)\r
+  set(XAMINKERNEL zamin.S)\r
+  set(SMAXKERNEL max.S)\r
+  set(DMAXKERNEL max.S)\r
+  set(QMAXKERNEL max.S)\r
+  set(SMINKERNEL min.S)\r
+  set(DMINKERNEL min.S)\r
+  set(QMINKERNEL min.S)\r
+  set(ISAMAXKERNEL iamax.S)\r
+  set(IDAMAXKERNEL iamax.S)\r
+  set(IQAMAXKERNEL iamax.S)\r
+  set(ICAMAXKERNEL izamax.S)\r
+  set(IZAMAXKERNEL izamax.S)\r
+  set(IXAMAXKERNEL izamax.S)\r
+  set(ISAMINKERNEL iamin.S)\r
+  set(IDAMINKERNEL iamin.S)\r
+  set(IQAMINKERNEL iamin.S)\r
+  set(ICAMINKERNEL izamin.S)\r
+  set(IZAMINKERNEL izamin.S)\r
+  set(IXAMINKERNEL izamin.S)\r
+  set(ISMAXKERNEL iamax.S)\r
+  set(IDMAXKERNEL iamax.S)\r
+  set(IQMAXKERNEL iamax.S)\r
+  set(ISMINKERNEL iamin.S)\r
+  set(IDMINKERNEL iamin.S)\r
+  set(IQMINKERNEL iamin.S)\r
+  set(SASUMKERNEL asum.S)\r
+  set(DASUMKERNEL asum.S)\r
+  set(CASUMKERNEL zasum.S)\r
+  set(ZASUMKERNEL zasum.S)\r
+  set(QASUMKERNEL asum.S)\r
+  set(XASUMKERNEL zasum.S)\r
+  set(SAXPYKERNEL axpy.S)\r
+  set(DAXPYKERNEL axpy.S)\r
+  set(CAXPYKERNEL zaxpy.S)\r
+  set(ZAXPYKERNEL zaxpy.S)\r
+  set(QAXPYKERNEL axpy.S)\r
+  set(XAXPYKERNEL zaxpy.S)\r
+  set(SCOPYKERNEL copy.S)\r
+  set(DCOPYKERNEL copy.S)\r
+  set(CCOPYKERNEL zcopy.S)\r
+  set(ZCOPYKERNEL zcopy.S)\r
+  set(QCOPYKERNEL copy.S)\r
+  set(XCOPYKERNEL zcopy.S)\r
+  set(SDOTKERNEL dot.S)\r
+  set(DDOTKERNEL dot.S)\r
+  set(CDOTKERNEL zdot.S)\r
+  set(ZDOTKERNEL zdot.S)\r
+  set(QDOTKERNEL dot.S)\r
+  set(XDOTKERNEL zdot.S)\r
+  set(SNRM2KERNEL nrm2.S)\r
+  set(DNRM2KERNEL nrm2.S)\r
+  set(QNRM2KERNEL nrm2.S)\r
+  set(CNRM2KERNEL znrm2.S)\r
+  set(ZNRM2KERNEL znrm2.S)\r
+  set(XNRM2KERNEL znrm2.S)\r
+  set(SROTKERNEL rot.S)\r
+  set(DROTKERNEL rot.S)\r
+  set(QROTKERNEL rot.S)\r
+  set(CROTKERNEL zrot.S)\r
+  set(ZROTKERNEL zrot.S)\r
+  set(XROTKERNEL zrot.S)\r
+  set(SSCALKERNEL scal.S)\r
+  set(DSCALKERNEL scal.S)\r
+  set(CSCALKERNEL zscal.S)\r
+  set(ZSCALKERNEL zscal.S)\r
+  set(QSCALKERNEL scal.S)\r
+  set(XSCALKERNEL zscal.S)\r
+  set(SSWAPKERNEL swap.S)\r
+  set(DSWAPKERNEL swap.S)\r
+  set(CSWAPKERNEL zswap.S)\r
+  set(ZSWAPKERNEL zswap.S)\r
+  set(QSWAPKERNEL swap.S)\r
+  set(XSWAPKERNEL zswap.S)\r
+  set(SGEMVNKERNEL gemv_n.S)\r
+  set(SGEMVTKERNEL gemv_t.S)\r
+  set(DGEMVNKERNEL gemv_n.S)\r
+  set(DGEMVTKERNEL gemv_t.S)\r
+  set(CGEMVNKERNEL zgemv_n.S)\r
+  set(CGEMVTKERNEL zgemv_t.S)\r
+  set(ZGEMVNKERNEL zgemv_n.S)\r
+  set(ZGEMVTKERNEL zgemv_t.S)\r
+  set(QGEMVNKERNEL gemv_n.S)\r
+  set(QGEMVTKERNEL gemv_t.S)\r
+  set(XGEMVNKERNEL zgemv_n.S)\r
+  set(XGEMVTKERNEL zgemv_t.S)\r
+  set(SCABS_KERNEL cabs.S)\r
+  set(DCABS_KERNEL cabs.S)\r
+  set(QCABS_KERNEL cabs.S)\r
+  set(LSAME_KERNEL lsame.S)\r
+  set(SAXPBYKERNEL ../arm/axpby.c)\r
+  set(DAXPBYKERNEL ../arm/axpby.c)\r
+  set(CAXPBYKERNEL ../arm/zaxpby.c)\r
+  set(ZAXPBYKERNEL ../arm/zaxpby.c)\r
+endmacro ()\r
index d9c180f..9635b21 100644 (file)
@@ -12,6 +12,27 @@ function(ParseGetArchVars GETARCH_IN)
   endforeach ()
 endfunction ()
 
+# Reads a Makefile into CMake vars.
+# TODO: read nested Makefiles (I think 1 level should do)
+# TODO: respect IFDEF/IFNDEF?
+# TODO: regex replace makefile vars, e.g. $(TSUFFIX) is set to the target arch in the var CGEMMOTCOPYOBJ = cgemm_otcopy$(TSUFFIX).$(SUFFIX)
+# TODO: bail when makefile is missing, like -include
+function(ParseMakefileVars MAKEFILE_IN)
+  message(STATUS "Reading vars from ${MAKEFILE_IN}...")
+  file(STRINGS ${MAKEFILE_IN} makefile_contents)
+  foreach (makefile_line ${makefile_contents})
+    string(REGEX MATCH "([0-9_a-zA-Z]+)[ \t]*=[ \t]*(.+)$" line_match "${makefile_line}")
+    if (NOT "${line_match}" STREQUAL "")
+      set(var_name ${CMAKE_MATCH_1})
+      set(var_value ${CMAKE_MATCH_2})
+      set(${VAR_NAME} ${VAR_VALUE} PARENT_SCOPE)
+      message(STATUS "found var ${var_name} = ${var_value}")
+    else ()
+      message(STATUS "couldn't parse ${makefile_line} into a var")
+    endif ()
+  endforeach ()
+endfunction ()
+
 # Returns all combinations of the input list, as a list with colon-separated combinations
 # E.g. input of A B C returns A B C A:B A:C B:C
 # N.B. The input is meant to be a list, and to past a list to a function in CMake you must quote it (e.g. AllCombinations("${LIST_VAR}")).
@@ -75,6 +96,7 @@ endfunction ()
 #                               1 - compiles the sources for non-complex types only (SINGLE/DOUBLE)
 #                               2 - compiles for complex types only (COMPLEX/DOUBLE COMPLEX)
 #                               3 - compiles for all types, but changes source names for complex by prepending z (e.g. axpy.c becomes zaxpy.c)
+#                               STRING - compiles only the given type (e.g. DOUBLE)
 function(GenerateNamedObjects sources_in)
 
   if (DEFINED ARGV1)
@@ -105,6 +127,12 @@ function(GenerateNamedObjects sources_in)
     set(no_float_type false)
   endif ()
 
+  if (no_float_type)
+    set(float_list "DUMMY") # still need to loop once
+  else ()
+    set(float_list "${FLOAT_TYPES}")
+  endif ()
+
   set(real_only false)
   set(complex_only false)
   set(mangle_complex_sources false)
@@ -115,20 +143,17 @@ function(GenerateNamedObjects sources_in)
       set(complex_only true)
     elseif (${ARGV7} EQUAL 3)
       set(mangle_complex_sources true)
+    elseif (NOT ${ARGV7} EQUAL 0)
+      set(float_list ${ARGV7})
     endif ()
   endif ()
 
-  if (no_float_type)
-    set(float_list "DUMMY") # still need to loop once
-  else ()
-    set(float_list "${FLOAT_TYPES}")
-    if (complex_only)
-      list(REMOVE_ITEM float_list "SINGLE")
-      list(REMOVE_ITEM float_list "DOUBLE")
-    elseif (real_only)
-      list(REMOVE_ITEM float_list "COMPLEX")
-      list(REMOVE_ITEM float_list "ZCOMPLEX")
-    endif ()
+  if (complex_only)
+    list(REMOVE_ITEM float_list "SINGLE")
+    list(REMOVE_ITEM float_list "DOUBLE")
+  elseif (real_only)
+    list(REMOVE_ITEM float_list "COMPLEX")
+    list(REMOVE_ITEM float_list "ZCOMPLEX")
   endif ()
 
   set(OBJ_LIST_OUT "")
index 4524ad6..a1685db 100644 (file)
@@ -28,15 +28,15 @@ set(NU_SOURCES
 )
 
 # objects that need LOWER set
-GenerateCombinationObjects("${UL_SOURCES}" "LOWER" "U" "" 1)
+GenerateCombinationObjects("${UL_SOURCES}" "LOWER" "U" "" 1 "" "" 3)
 
 # objects that need TRANSA and UNIT set
 # N.B. BLAS wants to put the U/L from the filename in the *MIDDLE* because of course why not have a different naming scheme for every single object -hpa
-GenerateCombinationObjects("${NU_SOURCES}" "TRANSA;UNIT" "N;N" "" 3)
+GenerateCombinationObjects("${NU_SOURCES}" "TRANSA;UNIT" "N;N" "" 3 "" "" 3)
 
 # gbmv uses a lowercase n and t. WHY? WHO KNOWS!
-GenerateNamedObjects("gbmv_k.c" "" "gbmv_n")
-GenerateNamedObjects("gbmv_k.c" "TRANS" "gbmv_t")
+GenerateNamedObjects("gbmv_k.c" "" "gbmv_n" false "" "" "" 3)
+GenerateNamedObjects("gbmv_k.c" "TRANS" "gbmv_t" false "" "" "" 3)
 
 if (SMP)
 
index 6c25903..479b183 100644 (file)
@@ -1,67 +1,68 @@
 
 include_directories(${CMAKE_SOURCE_DIR})
+include("${CMAKE_SOURCE_DIR}/cmake/kernel.cmake")
 
 # Makeflie
 
+if (DEFINED TARGET_CORE)
+  #override CFLAGS += -DBUILD_KERNEL -DTABLE_NAME=gotoblas_$(TARGET_CORE)
+  set(BUILD_KERNEL 1)
+  set(KDIR "")
+  set(TSUFFIX "_${TARGET_CORE}")
+else ()
+  set(TARGET_CORE ${CORE})
+  set(KDIR "")
+  set(TSUFFIX "")
+endif ()
+
+SetDefaultL1()
+#-include $(KERNELDIR)/KERNEL.$(TARGET_CORE)
+#include $(KERNELDIR)/KERNEL
+ParseMakefileVars("${KERNELDIR}/KERNEL.${TARGET_CORE}")
+ParseMakefileVars("${KERNELDIR}/KERNEL")
+
 if (${ARCH} STREQUAL "x86")
   GenerateNamedObjects("${KERNELDIR}/cpuid.S" "")
 endif ()
 
-# TODO: Read from ${KERNELDIR}/KERNEL - some architectures use a different lsame
-set(LSAME_KERNEL lsame.S)
-set(SCABS_KERNEL cabs.S)
-set(DCABS_KERNEL cabs.S)
 # don't use float type name mangling here
-GenerateNamedObjects("${KERNELDIR}/${LSAME_KERNEL}" "F_INTERFACE" "lsame" 0 "" "" 1)
-GenerateNamedObjects("${KERNELDIR}/${SCABS_KERNEL}" "COMPLEX;F_INTERFACE" "scabs1" "" "" 1)
-GenerateNamedObjects("${KERNELDIR}/${DCABS_KERNEL}" "DOUBLE;COMPLEX;F_INTERFACE" "dcabs1" 0 "" "" 1)
-
+GenerateNamedObjects("${KERNELDIR}/${LSAME_KERNEL}" "F_INTERFACE" "lsame" false "" "" true)
+GenerateNamedObjects("${KERNELDIR}/${SCABS_KERNEL}" "COMPLEX;F_INTERFACE" "scabs1" false "" "" true)
+GenerateNamedObjects("${KERNELDIR}/${DCABS_KERNEL}" "DOUBLE;COMPLEX;F_INTERFACE" "dcabs1" false "" "" true)
 
 # Makefile.L1
 
 # TODO: need to read ${KERNELDIR}/KERNEL into CMake vars
-set(DAMAXKERNEL amax.S)
-set(DAMINKERNEL amax.S)
-set(DMAXKERNEL amax.S)
-set(DMINKERNEL amax.S)
-set(IDAMAXKERNEL iamax.S)
-set(IDAMINKERNEL iamax.S)
-set(IDMAXKERNEL iamax.S)
-set(IDMINKERNEL iamax.S)
-set(DASUMKERNEL asum.S)
-set(DAXPYKERNEL axpy.S)
-set(DCOPYKERNEL copy.S)
-set(DDOTKERNEL dot.S)
-set(DNRM2KERNEL nrm2.S)
-set(DROTKERNEL rot.S)
-set(DSCALKERNEL scal.S)
-set(DSWAPKERNEL swap.S)
-set(DAXPBYKERNEL ../arm/axpby.c)
-
-GenerateNamedObjects("${KERNELDIR}/${DAMAXKERNEL}" "USE_ABS" "amax_k")
-GenerateNamedObjects("${KERNELDIR}/${DAMINKERNEL}" "USE_ABS;USE_MIN" "amin_k")
-GenerateNamedObjects("${KERNELDIR}/${DMAXKERNEL}" "" "max_k")
-GenerateNamedObjects("${KERNELDIR}/${DMINKERNEL}" "" "min_k")
-GenerateNamedObjects("${KERNELDIR}/${IDAMAXKERNEL}" "USE_ABS" "i*amax_k")
-GenerateNamedObjects("${KERNELDIR}/${IDAMINKERNEL}" "USE_ABS;USE_MIN" "i*amin_k")
-GenerateNamedObjects("${KERNELDIR}/${IDMAXKERNEL}" "" "i*max_k")
-GenerateNamedObjects("${KERNELDIR}/${IDMINKERNEL}" "" "i*min_k")
-GenerateNamedObjects("${KERNELDIR}/${DASUMKERNEL}" "" "asum_k")
-GenerateNamedObjects("${KERNELDIR}/${DAXPYKERNEL}" "" "axpy_k")
-GenerateNamedObjects("${KERNELDIR}/${DCOPYKERNEL}" "C_INTERFACE" "copy_k")
-GenerateNamedObjects("${KERNELDIR}/${DDOTKERNEL}" "" "dot_k")
-GenerateNamedObjects("${KERNELDIR}/${DNRM2KERNEL}" "" "nrm2_k")
-GenerateNamedObjects("${KERNELDIR}/${DROTKERNEL}" "" "rot_k")
-GenerateNamedObjects("${KERNELDIR}/${DSCALKERNEL}" "" "scal_k")
-GenerateNamedObjects("${KERNELDIR}/${DSWAPKERNEL}" "" "swap_k")
-GenerateNamedObjects("${KERNELDIR}/${DAXPBYKERNEL}" "" "axpby_k")
+
+foreach (float_type ${FLOAT_TYPES})
+
+  # a bit of metaprogramming here to pull out the appropriate KERNEL var
+  string(SUBSTRING ${float_type} 0 1 float_char)
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}AMAXKERNEL}" "USE_ABS" "amax_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}AMINKERNEL}" "USE_ABS;USE_MIN" "amin_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}MAXKERNEL}" "" "max_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}MINKERNEL}" "" "min_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${I${float_char}AMAXKERNEL}" "USE_ABS" "i*amax_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${I${float_char}AMINKERNEL}" "USE_ABS;USE_MIN" "i*amin_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${I${float_char}MAXKERNEL}" "" "i*max_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${I${float_char}MINKERNEL}" "" "i*min_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}ASUMKERNEL}" "" "asum_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}AXPYKERNEL}" "" "axpy_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}COPYKERNEL}" "C_INTERFACE" "copy_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}DOTKERNEL}" "" "dot_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}NRM2KERNEL}" "" "nrm2_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}ROTKERNEL}" "" "rot_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}SCALKERNEL}" "" "scal_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}SWAPKERNEL}" "" "swap_k" false "" "" false ${float_type})
+  GenerateNamedObjects("${KERNELDIR}/${${float_char}AXPBYKERNEL}" "" "axpby_k" false "" "" false ${float_type})
+endforeach ()
 
 # Makefile.L2
 
 GenerateNamedObjects("${KERNELDIR}/gemv_n.S" "DOUBLE")
 GenerateNamedObjects("${KERNELDIR}/gemv_t.S" "TRANS")
-GenerateCombinationObjects("generic/symv_k.c" "LOWER" "U" "" 1)
-GenerateNamedObjects("generic/ger.c" "" "ger_k")
+GenerateCombinationObjects("generic/symv_k.c" "LOWER" "U" "" 1 "" "" 3)
+GenerateNamedObjects("generic/ger.c" "" "ger_k" false "" "" "" 3)
 
 # Makefile.L3
 
@@ -77,7 +78,7 @@ set(DGEMMITCOPYOBJ gemm_itcopy)
 set(DGEMMONCOPYOBJ gemm_oncopy)
 set(DGEMMOTCOPYOBJ gemm_otcopy)
 
-GenerateNamedObjects("${KERNELDIR}/${DGEMMKERNEL}" "" "gemm_kernel")
+GenerateNamedObjects("${KERNELDIR}/${DGEMMKERNEL}" "" "gemm_kernel" false "" "" "" 3)
 
 if (DGEMMINCOPY)
   GenerateNamedObjects("${KERNELDIR}/${DGEMMINCOPY}" "" "${DGEMMINCOPYOBJ}")