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

Add parallelization to SecureArray's operations #60

Open
2 tasks
ArseniyKholod opened this issue Jan 30, 2025 · 4 comments
Open
2 tasks

Add parallelization to SecureArray's operations #60

ArseniyKholod opened this issue Jan 30, 2025 · 4 comments

Comments

@ArseniyKholod
Copy link
Collaborator

ArseniyKholod commented Jan 30, 2025

Since SecureArray holds many ciphertexts, its operations can be easily parallelized when iterating over the ciphertexts.

I would add a macro, something like was done in Trixi.jl PR:

macro threaded(expr)
  # esc(quote ... end) as suggested in https://github.com/JuliaLang/julia/issues/23221
  return esc(quote
    if Threads.nthreads() == 1 || !threads_enabled
      $(expr)
    else
      Threads.@threads $(expr)
    end
  end)
end

I have also introduced the global boolean variable threads_enabled, allowing users to control parallelization.

What do you think?

  • Is OpenFHE thread-safe? Ask in discourse.
  • Threads.@threads check
@ArseniyKholod ArseniyKholod mentioned this issue Jan 30, 2025
3 tasks
@sloede
Copy link
Member

sloede commented Jan 31, 2025

Instead of a global variable, I suggest we use scoped values to allow for more fine-grained control. E.g., something like this

using Base.ScopedValues: ScopedValue, with

const MULTITHREADING_ENABLED = ScopedValue(false)

with_multithreading(f; enabled=true) = with(f, MULTITHREADING_ENABLED => enabled)
enable_multithreading(enabled=true) = MULTITHREADING_ENABLED[] = enabled
disable_multithreading() = enable_multithreading(false)

export with_multithreading, enable_multithreading, disable_multithreading

macro threaded(expr)
  # esc(quote ... end) as suggested in https://github.com/JuliaLang/julia/issues/23221
  return esc(quote
    if Threads.nthreads() == 1 || !MULTITHREADING_ENABLED[]
      $(expr)
    else
      Threads.@threads $(expr)
    end
  end)
end

Then, inside a SA.jl function that should allow for multithreading, we can just use @threaded as you suggested.

On the user side, one can then either enable/disable multithreading globally (through enable_multithreading()/disable_multithreading()) or enable/disable it locally, using

with_multithreading() do
    # this code will run with multithreading enabled...

    with_multithreading(enabled=false) do
        # while this part runs without multithreading
    end
end

Note that scoped values are only supported since Julia v1.11, thus we either need to up the minimum Julia version to v1.11 or use @vchuravy's ScopedValues.jl package for now (which works with Julia v1.8+).

What do you think?

@ArseniyKholod
Copy link
Collaborator Author

Great! Looks like a good solution. I think to require Julia 1.11 is not a big deal. Then I will implement this after #59 is merged

@sloede
Copy link
Member

sloede commented Jan 31, 2025

Then I will implement this after #59 is merged

Sounds good to me 👍

@sloede
Copy link
Member

sloede commented Jan 31, 2025

One question to @vchuravy though:

In SecureArithmetic.jl, performing this kind of "internal" parallelization is usually over just a handful (probably usually less then 10, but most certainly less than 100) objects. The operations that are being performed are very heavy though, and might require on the order of seconds (and sometimes minutes). Is Threads.@threads the way to go in such a situation or should we use some other kind of Julia-based multithreading approach?

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

No branches or pull requests

2 participants