OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Memory management while loading python in C#

  • Thread starter Thread starter Sahadev Poudel
  • Start date Start date
S

Sahadev Poudel

Guest
I am calling python function in C#. It loads deep learning model in C# framework successfully. However, i wanna release memory when task is done (for example detection/inference) but i am facing problem on it. I cannot release memory, as i wanna do other multiple tasks without closing an application. Currently I am using PythonNet for it. So, when i click Button3, i wanna release memory but objects hold memory of 11 gb without releasing it. I need some suggestion. I have uploaded code here.

Code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using Python.Runtime;
using VOModel;`

public class Detection : IDisposable
{
    private PyObject model_object;
    private string model_path = string.Empty;
    private List<PyObject> model_objs = new List<PyObject>();
    private bool _disposed = false;
    private bool pythonEngineInitialized = false;

    public void SetEnvironment(string conda_path)
    {
        if (string.IsNullOrEmpty(conda_path))
        {
            throw new ArgumentNullException(nameof(conda_path));
        }

        Environment.SetEnvironmentVariable("PATH", conda_path + ";" + Environment.GetEnvironmentVariable("PATH"));
        Environment.SetEnvironmentVariable("PYTHONHOME", conda_path);
        Environment.SetEnvironmentVariable("PYTHONPATH", conda_path + "\\Lib");
        PythonEngine.PythonHome = conda_path;
        if (!pythonEngineInitialized)
        {
            PythonEngine.Initialize();
            ClsModelMgr.Ins.BeginAllowThreads();
            pythonEngineInitialized = true;
        }
    }

    public PyObject LoadNet_OD(string vomodel_path, string weights_path)
    {
        using (Py.GIL())
        {
            model_path = vomodel_path;
            Directory.SetCurrentDirectory(vomodel_path);
            PyObject pyObject = Py.Import("sys");
            pyObject.GetAttr("path").InvokeMethod("append", new PyString(vomodel_path));
            dynamic val = Py.Import("loadnet_od");
            dynamic val2 = val.load_net(weights_path);
            model_object = val2;
            model_objs.Add(model_object);  // Ensure the model object is tracked for disposal
            Console.WriteLine("Load Done");
            return val2;
        }
    }

    public dynamic ExecutePythonCode(string code)
    {
        using (Py.GIL())
        {
            using (PyScope scope = Py.CreateScope())
            {
                scope.Exec(code);
                return null; // Modify as needed to return the result
            }
        }
    }

    public dynamic GetModelObject()
    {
        if (model_object == null)
        {
            throw new InvalidOperationException("Model is not loaded.");
        }

        return model_object;
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                foreach (var obj in model_objs)
                {
                    obj.Dispose();
                }
                model_objs.Clear();

                model_object?.Dispose();
                model_object = null;

                if (pythonEngineInitialized)
                {
                    PythonEngine.Shutdown();
                    pythonEngineInitialized = false;
                }
            }
            _disposed = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~Detection()
    {
        Dispose(false);
    }
}

namespace Memory_Test
{
    public partial class Form1 : Form
    {
        Detection od_model;
        PyObject model_obj_OD;
        bool pythonEngineInitialized = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Load
            string pypath = @"C:\Users\user\AppData\Local\Programs\Python\Python38";
            string wpath = @"C:\Users\user\Desktop\DL\best.pt";
            string vood_path = @"C:\Users\user\Desktop\DL\VOModels";

            // Initialize Detection object
            if (od_model == null)
            {
                od_model = new Detection();
                od_model.SetEnvironment(pypath);
                pythonEngineInitialized = true;
            }

            try
            {
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                model_obj_OD = od_model.LoadNet_OD(vood_path, wpath);
                stopwatch.Stop();
                Console.WriteLine("Time taken to load model: " + stopwatch.ElapsedMilliseconds + "ms");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"An error occurred while loading the model: {ex.Message}");
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            ReleaseMemory();
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            ReleaseMemory();
            base.OnFormClosing(e);
        }

        private void ReleaseMemory()
        {
            // Dispose of model_obj_OD if initialized
            if (model_obj_OD != null)
            {
                model_obj_OD.Dispose();
                model_obj_OD = null;
            }

            // Dispose of the Detection object
            if (od_model != null)
            {
                od_model.Dispose();
                od_model = null;
            }

            // If the Python engine was initialized, shut it down
            if (pythonEngineInitialized)
            {
                try
                {
                    PythonEngine.Shutdown();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"An error occurred while shutting down the Python engine: {ex.Message}");
                }
                finally
                {
                    pythonEngineInitialized = false;
                }
            }

            // Perform garbage collection to release any remaining resources
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
    }
}

'Here is an image'
<p>I am calling python function in C#. It loads deep learning model in C# framework successfully. However, i wanna release memory when task is done (for example detection/inference) but i am facing problem on it. I cannot release memory, as i wanna do other multiple tasks without closing an application. Currently I am using PythonNet for it. So, when i click Button3, i wanna release memory but objects hold memory of 11 gb without releasing it. I need some suggestion. I have uploaded code here.</p>
<pre><code>using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using Python.Runtime;
using VOModel;`

public class Detection : IDisposable
{
private PyObject model_object;
private string model_path = string.Empty;
private List<PyObject> model_objs = new List<PyObject>();
private bool _disposed = false;
private bool pythonEngineInitialized = false;

public void SetEnvironment(string conda_path)
{
if (string.IsNullOrEmpty(conda_path))
{
throw new ArgumentNullException(nameof(conda_path));
}

Environment.SetEnvironmentVariable("PATH", conda_path + ";" + Environment.GetEnvironmentVariable("PATH"));
Environment.SetEnvironmentVariable("PYTHONHOME", conda_path);
Environment.SetEnvironmentVariable("PYTHONPATH", conda_path + "\\Lib");
PythonEngine.PythonHome = conda_path;
if (!pythonEngineInitialized)
{
PythonEngine.Initialize();
ClsModelMgr.Ins.BeginAllowThreads();
pythonEngineInitialized = true;
}
}

public PyObject LoadNet_OD(string vomodel_path, string weights_path)
{
using (Py.GIL())
{
model_path = vomodel_path;
Directory.SetCurrentDirectory(vomodel_path);
PyObject pyObject = Py.Import("sys");
pyObject.GetAttr("path").InvokeMethod("append", new PyString(vomodel_path));
dynamic val = Py.Import("loadnet_od");
dynamic val2 = val.load_net(weights_path);
model_object = val2;
model_objs.Add(model_object); // Ensure the model object is tracked for disposal
Console.WriteLine("Load Done");
return val2;
}
}

public dynamic ExecutePythonCode(string code)
{
using (Py.GIL())
{
using (PyScope scope = Py.CreateScope())
{
scope.Exec(code);
return null; // Modify as needed to return the result
}
}
}

public dynamic GetModelObject()
{
if (model_object == null)
{
throw new InvalidOperationException("Model is not loaded.");
}

return model_object;
}

protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
foreach (var obj in model_objs)
{
obj.Dispose();
}
model_objs.Clear();

model_object?.Dispose();
model_object = null;

if (pythonEngineInitialized)
{
PythonEngine.Shutdown();
pythonEngineInitialized = false;
}
}
_disposed = true;
}
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

~Detection()
{
Dispose(false);
}
}

namespace Memory_Test
{
public partial class Form1 : Form
{
Detection od_model;
PyObject model_obj_OD;
bool pythonEngineInitialized = false;

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
// Load
string pypath = @"C:\Users\user\AppData\Local\Programs\Python\Python38";
string wpath = @"C:\Users\user\Desktop\DL\best.pt";
string vood_path = @"C:\Users\user\Desktop\DL\VOModels";

// Initialize Detection object
if (od_model == null)
{
od_model = new Detection();
od_model.SetEnvironment(pypath);
pythonEngineInitialized = true;
}

try
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
model_obj_OD = od_model.LoadNet_OD(vood_path, wpath);
stopwatch.Stop();
Console.WriteLine("Time taken to load model: " + stopwatch.ElapsedMilliseconds + "ms");
}
catch (Exception ex)
{
MessageBox.Show($"An error occurred while loading the model: {ex.Message}");
}
}

private void button3_Click(object sender, EventArgs e)
{
ReleaseMemory();
}

protected override void OnFormClosing(FormClosingEventArgs e)
{
ReleaseMemory();
base.OnFormClosing(e);
}

private void ReleaseMemory()
{
// Dispose of model_obj_OD if initialized
if (model_obj_OD != null)
{
model_obj_OD.Dispose();
model_obj_OD = null;
}

// Dispose of the Detection object
if (od_model != null)
{
od_model.Dispose();
od_model = null;
}

// If the Python engine was initialized, shut it down
if (pythonEngineInitialized)
{
try
{
PythonEngine.Shutdown();
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred while shutting down the Python engine: {ex.Message}");
}
finally
{
pythonEngineInitialized = false;
}
}

// Perform garbage collection to release any remaining resources
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
}
</code></pre>
<p>'<a href="https://i.sstatic.net/YATsbdx7.png" rel="nofollow noreferrer">Here is an image</a>'</p>
 

Latest posts

J
Replies
0
Views
1
jbowerbir
J
Top