Skip to content

Commit

Permalink
Add likwid-sysfeatures --saveall and --loadall
Browse files Browse the repository at this point in the history
  • Loading branch information
ipatix committed Dec 9, 2024
1 parent 5567045 commit ff192f7
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 21 deletions.
124 changes: 107 additions & 17 deletions src/applications/likwid-sysfeatures.lua
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ local function usage()
print_stdout("-s, --set <feature(s)>\t Set feature(s) to the given value")
print_stdout(" \t format: <category>.<name>=<value> or just <name>=<value> if unique")
print_stdout(" \t can be a comma-separated list of features")
print_stdout(" --saveall \t Save all available rw-features to file")
print_stdout(" --loadall \t Load all features from file")
print_stdout("-O\t\t\t Output results in CSV")
print_stdout("-V, --verbose <level>\t Set verbosity\n")
end
Expand Down Expand Up @@ -121,7 +123,7 @@ local verbose = 0
local output_csv = false

-- parse the command line
for opt,arg in likwid.getopt(arg, {"h","v","l","p","d:","g:","s:","a", "O","help","version","list", "print", "set:", "get:","all", "cpus:", "V:", "verbose:"}) do
for opt,arg in likwid.getopt(arg, {"h","v","l","p","d:","g:","s:","a", "O","help","version","list", "print", "set:", "get:","all", "cpus:", "V:", "verbose:", "saveall:", "loadall:"}) do
if (type(arg) == "string") then
local s,e = arg:find("-");
if s == 1 then
Expand Down Expand Up @@ -152,6 +154,10 @@ for opt,arg in likwid.getopt(arg, {"h","v","l","p","d:","g:","s:","a", "O","help
getList = likwid.stringsplit(arg, ",")
elseif opt == "s" or opt == "set" then
setList = likwid.stringsplit(arg, ",")
elseif opt == "saveall" then
saveFeatures = arg
elseif opt == "loadall" then
loadFeatures = arg
elseif opt == "?" then
print_stderr("Invalid commandline option -"..arg)
os.exit(1)
Expand All @@ -163,12 +169,12 @@ end


-- validate command line input
if (not printDevices) and (not listFeatures) and (not allFeatures) and (#getList == 0) and (#setList == 0) then
if (not printDevices) and (not listFeatures) and (not allFeatures) and (not saveFeatures) and (not loadFeatures) and (#getList == 0) and (#setList == 0) then
print_stderr("No operations specified, exiting...")
os.exit(1)
end
if (printDevices or listFeatures or allFeatures) and (#getList > 0 or #setList > 0) then
print_stderr("Cannot list features and get/set at the same time")
if (printDevices or listFeatures or allFeatures or saveFeatures or loadFeatures) and (#getList > 0 or #setList > 0) then
print_stderr("Cannot list features and get/set/load/save at the same time")
os.exit(1)
end
if #devList == 0 then
Expand Down Expand Up @@ -200,20 +206,21 @@ end
local ft_list = likwid.sysFeatures_list()

-- print available devices
device_types = {}
device_types[likwid.hwthread] = "HWThread (T)"
device_types[likwid.core] = "Core (C)"
device_types[likwid.numa] = "NUMA (M)"
device_types[likwid.die] = "Die (D)"
device_types[likwid.socket] = "Socket (S)"
device_types[likwid.node] = "Node (N)"
if likwid.nvSupported() then
device_types[likwid.nvidia_gpu] = "Nvidia GPU (GN)"
end
if likwid.rocmSupported() then
device_types[likwid.amd_gpu] = "AMD GPU (GA)"
end

if printDevices then
device_types = {}
device_types[likwid.hwthread] = "HWThread (T)"
device_types[likwid.core] = "Core (C)"
device_types[likwid.numa] = "NUMA (M)"
device_types[likwid.die] = "Die (D)"
device_types[likwid.socket] = "Socket (S)"
device_types[likwid.node] = "Node (N)"
if likwid.nvSupported() then
device_types[likwid.nvidia_gpu] = "Nvidia GPU (GN)"
end
if likwid.rocmSupported() then
device_types[likwid.amd_gpu] = "AMD GPU (GA)"
end
for devtype, name in pairs(device_types) do
print(string.format("%s:", name))
devices = likwid.getAvailableDevices(devtype)
Expand Down Expand Up @@ -384,5 +391,88 @@ if #setList > 0 and #devList > 0 then
os.exit(0)
end

-- save all read/write features to file
if saveFeatures then
local file = io.open(saveFeatures, "w")
-- iterate over all device types
for devtype, _ in pairs(device_types) do
-- iterate over all features
for _,f in pairs(ft_list) do
local full_name = string.format("%s.%s", f.Category, f.Name)
-- only allow matching device types and if feature is readable and writable
if f.TypeID ~= devtype or f.ReadOnly or f.WriteOnly then
goto next_feat
end

-- actually read the features
for _, dev in pairs(likwid.getAllDevices(devtype)) do
local lw_dev = likwid.createDevice(devtype, dev)
local v, err = likwid.sysFeatures_get(full_name, lw_dev)
if err then
print_stderr(string.format("Failed to get feature '%s' on device %s:%d: %s", full_name, lw_dev:typeName(), lw_dev:id(), err))
goto next_feat
end
file:write(string.format("%s.%s@%s=%s\n", f.Category, f.Name, lw_dev:id(), v))
end

::next_feat::
end
end

file:close()

likwid.finalizeSysFeatures()
os.exit(0)
end

-- load all features from file
if loadFeatures then
for line in io.lines(loadFeatures) do
-- split string like the following: cpu_freq.governor@5=schedutil
local part1 = likwid.stringsplit(line, "=")
if #part1 ~= 2 then
print_stderr("Invalid line: " .. line)
os.exit(1)
end
local part2 = likwid.stringsplit(part1[1], "@")
if #part2 ~= 2 then
print_stderr("Invalid line: " .. line)
os.exit(1)
end
part3 = likwid.stringsplit(part2[1], ".")
if #part3 ~= 2 then
print_stderr("Invalid line: " .. line)
os.exit(1)
end
local feat_cat = part3[1]
local feat_name = part3[2]
local dev_id = part2[2]
local value = part1[2]

local full_name = string.format("%s.%s", feat_cat, feat_name)

-- get device type of this particular feature
local devtype = nil
for _, f in pairs(ft_list) do
if f.Name == feat_name and f.Category == feat_cat then
devtype = f.TypeID
break
end
end
if not devtype then
print_stderr(string.format("Unknown feature: '%s'", full_name))
os.exit(1)
end
local lw_dev = likwid.createDevice(devtype, dev_id)
local success, err = likwid.sysFeatures_set(full_name, lw_dev, value)
if not success then
print_stderr(string.format("Failed to set feature '%s' on device %s:%d to %s: %s", full_name, lw_dev:typeName(), lw_dev:id(), value, err))
end
end

likwid.finalizeSysFeatures()
os.exit(0)
end

likwid.finalizeSysFeatures()
os.exit(0)
1 change: 1 addition & 0 deletions src/applications/likwid.lua
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ likwid.finalizeSysFeatures = likwid_finalizeSysFeatures
likwid.createDevice = likwid_createDevice
likwid.createDevicesFromString = likwid_createDevicesFromString
likwid.getAvailableDevices = likwid_getAvailableDevices
likwid.getAllDevices = likwid_getAllDevices

likwid.getCudaTopology = likwid_getCudaTopology
likwid.putCudaTopology = likwid_putCudaTopology
Expand Down
29 changes: 25 additions & 4 deletions src/luawid.c
Original file line number Diff line number Diff line change
Expand Up @@ -3828,14 +3828,24 @@ static int lua_likwid_destroyDevice(lua_State *L)
return 0;
}

static int lua_likwid_getAvailableDevices(lua_State *L)
static int lua_likwid_getDevices(lua_State *L, bool all)
{
const LikwidDeviceType type = luaL_checknumber(L, 1);
char **id_list = NULL;
size_t id_list_len = 0;
int err = likwid_device_get_available(type, &id_list, &id_list_len);
if (err < 0)
luaL_error(L, "likwid_device_get_available failed: %s", strerror(-err));
int err;
if (all)
{
err = likwid_device_get_all(type, &id_list, &id_list_len);
if (err < 0)
luaL_error(L, "likwid_device_get_all failed: %s", strerror(-err));
}
else
{
err = likwid_device_get_available(type, &id_list, &id_list_len);
if (err < 0)
luaL_error(L, "likwid_device_get_available failed: %s", strerror(-err));
}

lua_newtable(L);

Expand All @@ -3850,6 +3860,16 @@ static int lua_likwid_getAvailableDevices(lua_State *L)
return 1;
}

static int lua_likwid_getAvailableDevices(lua_State *L)
{
return lua_likwid_getDevices(L, false);
}

static int lua_likwid_getAllDevices(lua_State *L)
{
return lua_likwid_getDevices(L, true);
}

static int lua_likwiddevice_get_typeId(lua_State *L)
{
const LikwidDevice_t dev = *(LikwidDevice_t *)luaL_checkudata(L, 1, "LikwidDevice_t");
Expand Down Expand Up @@ -4249,6 +4269,7 @@ int __attribute__((visibility("default"))) luaopen_liblikwid(lua_State *L) {
lua_register(L, "likwid_createDevicesFromString",lua_likwid_createDevicesFromString);
lua_register(L, "likwid_createDevice",lua_likwid_createDevice);
lua_register(L, "likwid_getAvailableDevices",lua_likwid_getAvailableDevices);
lua_register(L, "likwid_getAllDevices",lua_likwid_getAllDevices);
#endif /* LIKWID_WITH_SYSFEATURES */
#ifdef __MIC__
setuid(0);
Expand Down

0 comments on commit ff192f7

Please sign in to comment.