From 737e08cd7a6046475b3db80ba41f98fa0d322bfd Mon Sep 17 00:00:00 2001 From: Edward Smyth Date: Mon, 1 Aug 2022 11:59:18 -0400 Subject: [PATCH] BLIS: Improve architecture selection at runtime Enable meaningful names as options for BLIS_ARCH_TYPE environment variable. For example, BLIS_ARCH_TYPE=zen4 or BLIS_ARCH_TYPE='ZEN4' or BLIS_ARCH_TYPE=6 will select the same code path (in this release). The meaningful names are not case sensitive. This implements change 1 in the Jira ticket below. Following review comments: 1. Use names from arch_t enum in function bli_env_get_var_arch_type() rather than directly using numbers. 2. AMD copyrights updated. AMD-Internal: [CPUPL-2235] Change-Id: I8cfd43d34765d5e8c7e35680d18825d9934753ad --- frame/base/bli_arch.c | 6 +- frame/base/bli_env.c | 151 +++++++++++++++++++++++++++++++++- frame/base/bli_env.h | 4 +- frame/include/bli_type_defs.h | 2 + 4 files changed, 159 insertions(+), 4 deletions(-) diff --git a/frame/base/bli_arch.c b/frame/base/bli_arch.c index 269623671..aa6940ba4 100644 --- a/frame/base/bli_arch.c +++ b/frame/base/bli_arch.c @@ -5,7 +5,7 @@ libraries. Copyright (C) 2014, The University of Texas at Austin - Copyright (C) 2018-2021, Advanced Micro Devices, Inc. All rights reserved. + Copyright (C) 2018-2022, Advanced Micro Devices, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -83,7 +83,7 @@ void bli_arch_set_id( void ) // Check the environment variable BLIS_ARCH_TYPE to see if the user // requested that we use a specific subconfiguration. - dim_t req_id = bli_env_get_var( "BLIS_ARCH_TYPE", -1 ); + dim_t req_id = bli_env_get_var_arch_type( "BLIS_ARCH_TYPE", -1 ); #ifndef BLIS_CONFIGURETIME_CPUID if ( req_id != -1 ) @@ -230,6 +230,8 @@ void bli_arch_set_id( void ) // enumeration that is typedef'ed in bli_type_defs.h. That is, the // index order of each string should correspond to the implied/assigned // enum value given to the corresponding BLIS_ARCH_ value. +// This must also be kept up-to-date with the bli_env_get_var_arch_type() +// function in bli_env.c static char* config_name[ BLIS_NUM_ARCHS ] = { "skx", diff --git a/frame/base/bli_env.c b/frame/base/bli_env.c index 23b8e059e..2cb9efd87 100644 --- a/frame/base/bli_env.c +++ b/frame/base/bli_env.c @@ -5,7 +5,7 @@ libraries. Copyright (C) 2014, The University of Texas at Austin - Copyright (C) 2018, Advanced Micro Devices, Inc. + Copyright (C) 2018-2022, Advanced Micro Devices, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -69,6 +69,155 @@ gint_t bli_env_get_var( const char* env, gint_t fallback ) return r_val; } +gint_t bli_env_get_var_arch_type( const char* env, gint_t fallback ) +{ + gint_t r_val; + char* str; + int i, size; + + // Query the environment variable and store the result in str. + str = getenv( env ); + + // Set the return value based on the string obtained from getenv(). + if ( str != NULL ) + { + // If there was no error, convert the string to an integer and + // prepare to return that integer. + r_val = ( gint_t )strtol( str, NULL, 10 ); + + if (r_val == 0) + { + // Could be deliberately 0 (currently meaning "skx") or + // a non-numeric value. We still allow direct specification + // of integer value to select code path. Non-zero integer + // values bypass this code block and are handled as before. + // Here we look for known meaningful names, and return 0 + // if we cannot find a match. + // This code MUST be kept in synch with arch_t enumeration + // in bli_type_defs.h and array config_name in bli_arch.c + + // convert string to lowercase + size = strlen(str); + for (i=0;i<=size;i++) + { + str[i] = tolower(str[i]); + } + + // Intel + if (strcmp(str, "skx") == 0) + { + r_val = BLIS_ARCH_SKX; + } + else if (strcmp(str, "knl") == 0) + { + r_val = BLIS_ARCH_KNL; + } + else if (strcmp(str, "knc") == 0) + { + r_val = BLIS_ARCH_KNC; + } + else if (strcmp(str, "haswell") == 0) + { + r_val = BLIS_ARCH_HASWELL; + } + else if (strcmp(str, "sandybridge") == 0) + { + r_val = BLIS_ARCH_SANDYBRIDGE; + } + else if (strcmp(str, "penryn") == 0) + { + r_val = BLIS_ARCH_PENRYN; + } + // AMD + else if (strcmp(str, "zen4") == 0) + { + r_val = BLIS_ARCH_ZEN4; + } + else if (strcmp(str, "zen3") == 0) + { + r_val = BLIS_ARCH_ZEN3; + } + else if (strcmp(str, "zen2") == 0) + { + r_val = BLIS_ARCH_ZEN2; + } + else if ((strcmp(str, "zen") == 0) || (strcmp(str, "zen1") == 0)) + { + r_val = BLIS_ARCH_ZEN; + } + else if (strcmp(str, "excavator") == 0) + { + r_val = BLIS_ARCH_EXCAVATOR; + } + else if (strcmp(str, "steamroller") == 0) + { + r_val = BLIS_ARCH_STEAMROLLER; + } + else if (strcmp(str, "piledriver") == 0) + { + r_val = BLIS_ARCH_PILEDRIVER; + } + else if (strcmp(str, "bulldozer") == 0) + { + r_val = BLIS_ARCH_BULLDOZER; + } + // ARM + else if (strcmp(str, "thunderx2") == 0) + { + r_val = BLIS_ARCH_THUNDERX2; + } + else if (strcmp(str, "cortexa57") == 0) + { + r_val = BLIS_ARCH_CORTEXA57; + } + else if (strcmp(str, "cortexa53") == 0) + { + r_val = BLIS_ARCH_CORTEXA53; + } + else if (strcmp(str, "cortexa15") == 0) + { + r_val = BLIS_ARCH_CORTEXA15; + } + else if (strcmp(str, "cortexa9") == 0) + { + r_val = BLIS_ARCH_CORTEXA9; + } + // IBM POWER + else if (strcmp(str, "power10") == 0) + { + r_val = BLIS_ARCH_POWER10; + } + else if (strcmp(str, "power9") == 0) + { + r_val = BLIS_ARCH_POWER9; + } + else if (strcmp(str, "power7") == 0) + { + r_val = BLIS_ARCH_POWER7; + } + else if (strcmp(str, "bgq") == 0) + { + r_val = BLIS_ARCH_BGQ; + } + // Generic + else if (strcmp(str, "generic") == 0) + { + r_val = BLIS_ARCH_GENERIC; + } + + // No else case means we return r_val=0, i.e. this behaves + // the same as generic bli_env_get_var(). + } + } + else + { + // If there was an error, use the "fallback" as the return value. + r_val = fallback; + } + + return r_val; +} + #if 0 #ifdef _MSC_VER #define strerror_r(errno,buf,len) strerror_s(buf,len,errno) diff --git a/frame/base/bli_env.h b/frame/base/bli_env.h index de86fadff..eaa778cd2 100644 --- a/frame/base/bli_env.h +++ b/frame/base/bli_env.h @@ -6,7 +6,7 @@ Copyright (C) 2014, The University of Texas at Austin Copyright (C) 2016, Hewlett Packard Enterprise Development LP - Copyright (C) 2018, Advanced Micro Devices, Inc. + Copyright (C) 2018-2022, Advanced Micro Devices, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -40,5 +40,7 @@ gint_t bli_env_get_var( const char* env, gint_t fallback ); //void bli_env_set_var( const char* env, dim_t value ); +gint_t bli_env_get_var_arch_type( const char* env, gint_t fallback ); + #endif diff --git a/frame/include/bli_type_defs.h b/frame/include/bli_type_defs.h index 4e28d8b46..47377aa25 100644 --- a/frame/include/bli_type_defs.h +++ b/frame/include/bli_type_defs.h @@ -990,6 +990,8 @@ typedef enum // string array in bli_arch.c. Whenever values are added/inserted // OR if values are rearranged, be sure to update the string array // in bli_arch.c. +// This must also be kept up-to-date with the bli_env_get_var_arch_type() +// function in bli_env.c typedef enum {