Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Looking for user feedback] Add support for per-application config profiles #251

Closed
ilya-zlobintsev opened this issue Jan 22, 2024 · 17 comments · Fixed by #424
Closed

[Looking for user feedback] Add support for per-application config profiles #251

ilya-zlobintsev opened this issue Jan 22, 2024 · 17 comments · Fixed by #424

Comments

@ilya-zlobintsev
Copy link
Owner

It would be nice if it was possible to create multiple config profiles, and automatically switch them based on currently running applications. An example use case would be to have one set of settings when you're running a specific game, another when you're running a compute workload etc.

If you're a user and you would find this feature useful, please say so.

Implementation details: ideally this would be done via a eBPF plugin that subscribes to process start/exit events.
bpftrace examples:

bpftrace -e 'tracepoint:syscalls:sys_enter_exec* { printf("SPAWN %d ", pid); join(args.argv); }'
bpftrace -e 'tracepoint:sched:sched_process_exit { printf("EXIT %d %s\n", args.pid, comm); }'

If this ends up being too difficult, another way would be to poll /proc, but need to make sure that it's not too expensive to do so

@43615
Copy link

43615 commented Jan 24, 2024

I'm not sure if I'd use this myself, but it would definitely be a nice bonus feature once full baseline support is there.

For a solid implementation, I'm thinking of a priority-based system (short-circuiting check down a list of conditions with associated profiles). The conditions could be simple checks for the presence of certain processes, maybe with the additional option of setting a custom command and matching on its exit code. Seems easy enough to implement with sysinfo and std::process.
I'm not a fan of using start/stop events since the daemon would forget the current state when restarted. Instead, I propose checking the conditions on a timer (every few seconds?). Any application that misbehaves when the parameters change would do so either way.

@ilya-zlobintsev
Copy link
Owner Author

The problem with scanning the process list every few seconds is that it requires scanning the entire /proc filesystem, which might be a relatively heavy operation. Currently the LACT daemon is very lightweight and doesn't do anything unless it actually needs to, and I'd like to keep it that way considering it's something that always runs in the background. The full scan would still need to be done on service startup to keep track of already existing processes though.

@ilya-zlobintsev
Copy link
Owner Author

Reference for self on how other projects do it:

@In-line
Copy link
Contributor

In-line commented Mar 5, 2024

Gamemode support is only thing needed

@FabianoIlCapo
Copy link

It would be nice if it was possible to create multiple config profiles, and automatically switch them based on currently running applications. An example use case would be to have one set of settings when you're running a specific game, another when you're running a compute workload etc.

Sounds like the equivalent of what the Nvidia control panel does (or did), that would be GOLDEN!

@Umio-Yasuno
Copy link
Contributor

I am developing a simple amdgpu profile switcher.
Some changes are required, but that tool could be used for LACT.

https://github.com/Umio-Yasuno/amdgpu-profile-switcher

@bioxz
Copy link

bioxz commented May 15, 2024

I would love to see this. I don't care about automatic switching, as I like to switch the profiles by hand even using the same application. I have a default undervolted and underclocked mode which allows me to use the GPU without its fans and a overclocked mode which is quite noisy, basically silent just using case fans.

Currently I'm using corectl which (in my eyes) does the whole profile thing in a weird and over complicated way (you can have multiple profiles active at once, partly overwriting others). Biggest "issue" right now is that you cannot ask the command line tool which profile is active, so you have to rely on the GUI to switch profiles.

Having a command/API to simply active a profile and another to request the current profile would be perfect, so I can build interfaces for a Plasma Widget and my Stream Deck.

@kiwi8sully
Copy link

I just want to preface this with that I have no training in the field whatsoever, but....... for my use....

Steam already exports $SteamAppId which can be used to switch profiles. It would be much cleaner/easier if the API had profile switching by that variable.
This is what I have currently

#!/bin/bash
#
# gamemode_profile.sh
# [Steam]>[Game]>[Properties]>[General]>[Launch Options] GAMEMODERUNEXEC="$HOME/bin/gamemode_profile.sh" gamemoderun %command%
ID=$( echo '{"command": "list_devices" }' | ncat -U /run/lactd.sock | cut -d , -f 2 | cut -d \" -f 6 )

confirm_pending_config() {
    echo '{"command": "confirm_pending_config", "args": { "command": "confirm" } }' | ncat -U /run/lactd.sock
}

set_power_profile_mode() {
    case "$1" in
    [0-6])
        echo '{"command":"set_performance_level","args":{"id":"'"$ID"'","performance_level":"manual"}}' | ncat -U /run/lactd.sock
        confirm_pending_config
        echo '{"command":"set_power_profile_mode","args":{"id":"'"$ID"'","index":'$1'}}' | ncat -U /run/lactd.sock
        confirm_pending_config
        ;;
    auto)
        echo '{"command":"set_performance_level","args":{"id":"'"$ID"'","performance_level":"manual"}}' | ncat -U /run/lactd.sock
        confirm_pending_config
        echo '{"command":"set_power_profile_mode", "args":{"id":"'"$ID"'","index":null}}' | ncat -U /run/lactd.sock
        confirm_pending_config
        echo '{"command":"set_performance_level","args":{"id":"'"$ID"'","performance_level":"auto"}}' | ncat -U /run/lactd.sock
        confirm_pending_config
        ;;
    *)
        echo "You need to specify a power profile [0-6] | auto"
        ;;
    esac
}

set_performance_level() {
    case "$1" in
    auto | low | high)
        echo '{"command":"set_performance_level","args":{"id":"'"$ID"'","performance_level":"manual"}}' | ncat -U /run/lactd.sock
        confirm_pending_config
        echo '{"command":"set_power_profile_mode","args":{"id":"'"$ID"'","index":null}}' | ncat -U /run/lactd.sock
        confirm_pending_config
        echo '{"command":"set_performance_level","args":{"id":"'"$ID"'","performance_level":"'$1'"}}' | ncat -U /run/lactd.sock
        confirm_pending_config
        ;;
    *)
        echo "You need to specify a performance level low | high auto"
        ;;
    esac
}

case $SteamAppId in
    570) # dota2
        set_performance_level high # ALL ON THE BLOCK THAT STAYS HOT
        export MANGOHUD=1
        #export MANGOHUD_CONFIG=throttling_status
        ;;
    804410) # [placeholder] The Making of Horizon Zero Dawn
        set_performance_level low # NEGLECTED FOR NOW
        ;;
    411180) # [placeholder] The International 5 - Player Profiles
        set_power_profile_mode 0 # DEFAULT
        ;;
    1151640 | 550) # Horizon Zero Dawn, l4d2
        set_power_profile_mode 1 # 3D_FULL_SCREEN
        export MANGOHUD=1
        #export MANGOHUD_CONFIG="wine,winesync"
        ;;
    1014370) # Bouncing DVD
        set_power_profile_mode 2 #POWER_SAVING
        ;;
    245550 ) # Video player ?
        set_power_profile_mode 3 # VIDEO
        ;;
    250820) # Steam VR
        set_power_profile_mode 4 # VR
        ;;
    230290) # Universe Sandbox
        set_power_profile_mode 5 # COMPUTE
        ;;
    230290) # Universe Sandbox
        set_power_profile_mode 6 # CUSTOM
        ;;
    *) # Catchall set to 3d full screen
        set_power_profile_mode 1 # 3D_FULL_SCREEN
        ;;
esac

# Custon configs need to be named [SteamAppId].conf NOT name.conf
# Uncomment to overide any MangoHud.conf file in $HOME/.config/MangoHud/
#export MANGOHUD_CONFIGFILE=$HOME/.config/MangoHud/$SteamAppId.conf

### BANG! ###
GAMEMODERUNEXEC=""
#LD_PRELOAD="${LD_PRELOAD}:/usr/lib/x86_64-linux-gnu/libgamemode.so"
exec "$@"
exit 0

You can see how this will get really messy with a big library and setting custom clocks etc ( I dont do that )

With a "load_profile" in the API if someone wants to poll and load they can script it, and the other option would be to start and load which gamemode provides a mechanism for already.

For my use case I dont use the lact gui now but it would be a nice feature to be able to manage profiles with it.

Thanks :)

@ilya-zlobintsev
Copy link
Owner Author

@bioxz @kiwi8sully Support for manual profiles management through the GUI and API landed in #327, there's no automatic switching but it should cover the use cases you've described.

@kiwi8sully
Copy link

kiwi8sully commented Sep 29, 2024

@ilya-zlobintsev Thankyou so much for this, basically down to one line now with version 0.5.7-0 :) https://github.com/kiwi8sully/lactdprofile.sh

@nPHYN1T3
Copy link

nPHYN1T3 commented Dec 13, 2024

I was here looking for some docs, there is no man page and I had wanted something like this. I was looking for syntax on just how to set the clocks from cli. Given I launch most my games or 3D tools via wrapper scripts I just wanted to be able to add something like lact cli -clocks=max before the program runs and lact cli -clocks=automatic when it exists.

@kiwi8sully
Copy link

I was here looking for some docs, there is no man page and I had wanted something like this. I was looking for syntax on just how to set the clocks from cli. Given I launch most my games or 3D tools via wrapper scripts I just wanted to be able to add something like lact cli -clocks=max before the program runs and lact cli -clocks=automatic when it exists.

If you look at the two scripts in https://github.com/kiwi8sully/lactdprofile.sh you should be able to determine how to set a profile and how to return the card to "null" profile from the command line. Just use the gui to set up a [high_clocks] profile.

@ilya-zlobintsev
Copy link
Owner Author

@kiwi8sully automatic switching has been implemented in #424, you can try it by using the test build.

Please let me know how it works for you. I've tested it on my setup, but there are different ways in which people might try to use this functionality, so there might be room for improvements for cases I have not considered.

@kiwi8sully
Copy link

@ilya-zlobintsev thank it seems to be working although profiles are not updated in the config.yaml until [switch automatically] is disabled and re-enabled.
Changing the profile by the picking one in the profile list changes the [power level mode:] in the main window but changing it via command line does not update the main gui window.
echo '{"command":"set_profile","args":{"name":"'"dota2"'"}}' | ncat -U /run/lactd.sock where dota2 is a custom profile.
cat /sys/class/drm/card1/device/pp_power_profile_mode | grep "*" returns
6 CUSTOM*: but the GUI shows BOOTUP_DEFAULT
This could be confusing for new users who are poking the damon and peeking the gui instead of peeking the sysfs

@ilya-zlobintsev
Copy link
Owner Author

profiles are not updated in the config.yaml until [switch automatically] is disabled and re-enabled.

If you mean the current_profile option - this is intended, there's no point in overwriting the config every time when the profile is changed automatically regardless of the setting.

changing it via command line does not update the main gui window.

Fixed in 4fe3c98

@kiwi8sully
Copy link

If you mean the current_profile option - this is intended, there's no point in overwriting the config every time when the profile is changed automatically regardless of the setting.

Sorry I mean if I edit a profile rule. Clicking [Save] does not save to config.yaml until the [switch automatically] check box is unchecked and then rechecked.
Specifically changing a profile from ...
rule: type: gamemode filter: null
to
rule: type: gamemode filter: name: dota2
config file is not updated when clicking [Save]. I have not tested with your most recent changes.

@ilya-zlobintsev
Copy link
Owner Author

Clicking [Save] does not save to config.yaml until the [switch automatically] check box is unchecked and then rechecked.

Ah, that makes sense. Fixed in 5882cf7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants