Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ obj/
.vs/
*.sln.docstates

# Ignore locally installed dotnet sdk
/dotnet/

# User-specific files
*.rsuser
*.suo
Expand Down
58 changes: 58 additions & 0 deletions GDeflateConsole/ArchiveManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;

namespace GDeflateConsole
{
public class ArchiveManager
{
public void CreateZipArchive(string archivePath, IEnumerable<string> files)
{
using (var fileStream = new FileStream(archivePath, FileMode.Create))
using (var archive = new ZipArchive(fileStream, ZipArchiveMode.Create))
{
foreach (var file in files)
{
archive.CreateEntryFromFile(file, Path.GetFileName(file));
}
}
}

public void ExtractZipArchive(string archivePath, string outputDirectory, Action<string, string> decompressFileAction)
{
using (var archive = ZipFile.OpenRead(archivePath))
{
bool hasGdefFiles = false;
foreach (var entry in archive.Entries)
{
string outputPath = Path.Combine(outputDirectory, entry.FullName);
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));

Check warning on line 30 in GDeflateConsole/ArchiveManager.cs

View workflow job for this annotation

GitHub Actions / Build Console Application (ubuntu-latest, linux-x64, Linux)

Possible null reference argument for parameter 'path' in 'DirectoryInfo Directory.CreateDirectory(string path)'.

Check warning on line 30 in GDeflateConsole/ArchiveManager.cs

View workflow job for this annotation

GitHub Actions / Build Console Application (ubuntu-latest, linux-x64, Linux)

Possible null reference argument for parameter 'path' in 'DirectoryInfo Directory.CreateDirectory(string path)'.

Check warning on line 30 in GDeflateConsole/ArchiveManager.cs

View workflow job for this annotation

GitHub Actions / Build Console Application (ubuntu-latest, linux-x64, Linux)

Possible null reference argument for parameter 'path' in 'DirectoryInfo Directory.CreateDirectory(string path)'.

Check warning on line 30 in GDeflateConsole/ArchiveManager.cs

View workflow job for this annotation

GitHub Actions / Build Console Application (windows-latest, win-x64, Windows)

Possible null reference argument for parameter 'path' in 'DirectoryInfo Directory.CreateDirectory(string path)'.

Check warning on line 30 in GDeflateConsole/ArchiveManager.cs

View workflow job for this annotation

GitHub Actions / Build Console Application (windows-latest, win-x64, Windows)

Possible null reference argument for parameter 'path' in 'DirectoryInfo Directory.CreateDirectory(string path)'.

Check warning on line 30 in GDeflateConsole/ArchiveManager.cs

View workflow job for this annotation

GitHub Actions / Build Console Application (windows-latest, win-x64, Windows)

Possible null reference argument for parameter 'path' in 'DirectoryInfo Directory.CreateDirectory(string path)'.

Check warning on line 30 in GDeflateConsole/ArchiveManager.cs

View workflow job for this annotation

GitHub Actions / Build Console Application (macos-latest, osx-x64, macOS)

Possible null reference argument for parameter 'path' in 'DirectoryInfo Directory.CreateDirectory(string path)'.

Check warning on line 30 in GDeflateConsole/ArchiveManager.cs

View workflow job for this annotation

GitHub Actions / Build Console Application (macos-latest, osx-x64, macOS)

Possible null reference argument for parameter 'path' in 'DirectoryInfo Directory.CreateDirectory(string path)'.

Check warning on line 30 in GDeflateConsole/ArchiveManager.cs

View workflow job for this annotation

GitHub Actions / Build Console Application (macos-latest, osx-x64, macOS)

Possible null reference argument for parameter 'path' in 'DirectoryInfo Directory.CreateDirectory(string path)'.

if (entry.Name.EndsWith(".gdef", StringComparison.OrdinalIgnoreCase))
{
hasGdefFiles = true;
// Create a temporary file for the gdef stream
string tempGdefFile = Path.GetTempFileName();
entry.ExtractToFile(tempGdefFile, true);

// Decompress the gdef file to its final destination
string finalPath = Path.ChangeExtension(outputPath, null);
decompressFileAction(tempGdefFile, finalPath);

File.Delete(tempGdefFile);
}
else
{
entry.ExtractToFile(outputPath, true);
}
}

if (!hasGdefFiles)
{
throw new InvalidDataException("The selected .zip archive does not contain any .gdef files to decompress.");
}
}
}
}
}
130 changes: 94 additions & 36 deletions GDeflateConsole/CudaRuntimeApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,73 @@ namespace GDeflateConsole
{
internal static class CudaRuntimeApi
{
// The name of the CUDA Runtime DLL. This may be version-specific
// (e.g., "cudart64_110.dll", "cudart64_12.dll").
// It must be in the system's PATH or alongside the executable.
private const string CudaRuntimeDll = "cudart64_12.dll";
private static readonly IntPtr _cudaRuntimeHandle;
private static readonly bool _isAvailable;

#region Delegates
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int cudaMalloc_t(out IntPtr devPtr, UIntPtr size);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int cudaMemcpy_t(IntPtr dst, IntPtr src, UIntPtr count, CudaMemcpyKind kind);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int cudaFree_t(IntPtr devPtr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int cudaStreamCreate_t(out IntPtr pStream);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int cudaStreamDestroy_t(IntPtr stream);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int cudaStreamSynchronize_t(IntPtr stream);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate IntPtr cudaGetErrorString_t(int error);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int cudaGetDeviceCount_t(out int count);
#endregion

#region Function Pointers
private static readonly cudaMalloc_t? _cudaMalloc;
private static readonly cudaMemcpy_t? _cudaMemcpy;
private static readonly cudaFree_t? _cudaFree;
private static readonly cudaStreamCreate_t? _cudaStreamCreate;
private static readonly cudaStreamDestroy_t? _cudaStreamDestroy;
private static readonly cudaStreamSynchronize_t? _cudaStreamSynchronize;
private static readonly cudaGetErrorString_t? _cudaGetErrorString;
private static readonly cudaGetDeviceCount_t? _cudaGetDeviceCount;
#endregion

static CudaRuntimeApi()
{
if (string.IsNullOrEmpty(NativeLibrary.CudartDllPath))
{
_isAvailable = false;
return;
}

_cudaRuntimeHandle = Kernel32.LoadLibrary(NativeLibrary.CudartDllPath);
if (_cudaRuntimeHandle == IntPtr.Zero)
{
_isAvailable = false;
return;
}

try
{
_cudaMalloc = Marshal.GetDelegateForFunctionPointer<cudaMalloc_t>(Kernel32.GetProcAddress(_cudaRuntimeHandle, "cudaMalloc"));
_cudaMemcpy = Marshal.GetDelegateForFunctionPointer<cudaMemcpy_t>(Kernel32.GetProcAddress(_cudaRuntimeHandle, "cudaMemcpy"));
_cudaFree = Marshal.GetDelegateForFunctionPointer<cudaFree_t>(Kernel32.GetProcAddress(_cudaRuntimeHandle, "cudaFree"));
_cudaStreamCreate = Marshal.GetDelegateForFunctionPointer<cudaStreamCreate_t>(Kernel32.GetProcAddress(_cudaRuntimeHandle, "cudaStreamCreate"));
_cudaStreamDestroy = Marshal.GetDelegateForFunctionPointer<cudaStreamDestroy_t>(Kernel32.GetProcAddress(_cudaRuntimeHandle, "cudaStreamDestroy"));
_cudaStreamSynchronize = Marshal.GetDelegateForFunctionPointer<cudaStreamSynchronize_t>(Kernel32.GetProcAddress(_cudaRuntimeHandle, "cudaStreamSynchronize"));
_cudaGetErrorString = Marshal.GetDelegateForFunctionPointer<cudaGetErrorString_t>(Kernel32.GetProcAddress(_cudaRuntimeHandle, "cudaGetErrorString"));
_cudaGetDeviceCount = Marshal.GetDelegateForFunctionPointer<cudaGetDeviceCount_t>(Kernel32.GetProcAddress(_cudaRuntimeHandle, "cudaGetDeviceCount"));
_isAvailable = true;
}
catch (Exception ex)
{
Console.WriteLine($"Failed to load CUDA runtime functions: {ex.Message}");
Kernel32.FreeLibrary(_cudaRuntimeHandle);
_isAvailable = false;
}
}

internal enum CudaMemcpyKind
{
Expand All @@ -19,47 +82,42 @@ internal enum CudaMemcpyKind
Default = 4
}

[DllImport(CudaRuntimeDll, SetLastError = true)]
internal static extern int cudaMalloc(out IntPtr devPtr, UIntPtr size);

[DllImport(CudaRuntimeDll, SetLastError = true)]
internal static extern int cudaMemcpy(IntPtr dst, IntPtr src, UIntPtr count, CudaMemcpyKind kind);

[DllImport(CudaRuntimeDll, SetLastError = true)]
internal static extern int cudaFree(IntPtr devPtr);

[DllImport(CudaRuntimeDll, SetLastError = true)]
internal static extern int cudaStreamCreate(out IntPtr pStream);

[DllImport(CudaRuntimeDll, SetLastError = true)]
internal static extern int cudaStreamDestroy(IntPtr stream);

[DllImport(CudaRuntimeDll, SetLastError = true)]
internal static extern int cudaStreamSynchronize(IntPtr stream);

[DllImport(CudaRuntimeDll, SetLastError = true)]
internal static extern IntPtr cudaGetErrorString(int error);

[DllImport(CudaRuntimeDll, SetLastError = true)]
internal static extern int cudaGetDeviceCount(out int count);
internal static int cudaMalloc(out IntPtr devPtr, UIntPtr size)
{
if (_cudaMalloc != null) return _cudaMalloc(out devPtr, size);
devPtr = IntPtr.Zero;
return -1;
}
internal static int cudaMemcpy(IntPtr dst, IntPtr src, UIntPtr count, CudaMemcpyKind kind) => _cudaMemcpy?.Invoke(dst, src, count, kind) ?? -1;
internal static int cudaFree(IntPtr devPtr) => _cudaFree?.Invoke(devPtr) ?? -1;
internal static int cudaStreamCreate(out IntPtr pStream)
{
if (_cudaStreamCreate != null) return _cudaStreamCreate(out pStream);
pStream = IntPtr.Zero;
return -1;
}
internal static int cudaStreamDestroy(IntPtr stream) => _cudaStreamDestroy?.Invoke(stream) ?? -1;
internal static int cudaStreamSynchronize(IntPtr stream) => _cudaStreamSynchronize?.Invoke(stream) ?? -1;
internal static IntPtr cudaGetErrorString(int error) => _cudaGetErrorString?.Invoke(error) ?? IntPtr.Zero;
internal static int cudaGetDeviceCount(out int count)
{
if (_cudaGetDeviceCount != null)
return _cudaGetDeviceCount(out count);
count = 0;
return -1;
}

// Helper method to check if CUDA is available
internal static bool IsCudaAvailable()
{
if (!_isAvailable)
return false;

try
{
int deviceCount;
int result = cudaGetDeviceCount(out deviceCount);
return result == 0 && deviceCount > 0;
}
catch (DllNotFoundException)
{
return false;
}
catch (EntryPointNotFoundException)
{
return false;
}
catch
{
return false;
Expand Down
60 changes: 60 additions & 0 deletions GDeflateConsole/GDeflateProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,66 @@ public void CompressFile(string inputFile, string outputFile)
}
}

public void CompressFilesToArchive(string[] inputFiles, string outputArchivePath, string format)
{
if (format == ".zip")
{
var tempFiles = new List<string>();
try
{
foreach (var inputFile in inputFiles)
{
string tempGdefFile = Path.GetTempFileName();
CompressFile(inputFile, tempGdefFile);
// Rename temp file to have .gdef extension for clarity in archive
string finalTempName = Path.ChangeExtension(tempGdefFile, ".gdef");
File.Move(tempGdefFile, finalTempName);
tempFiles.Add(finalTempName);
}
var archiveManager = new ArchiveManager();
archiveManager.CreateZipArchive(outputArchivePath, tempFiles);
}
finally
{
foreach (var file in tempFiles)
{
if (File.Exists(file))
File.Delete(file);
}
}
}
else if (format == ".gdef")
{
if (inputFiles.Length > 1)
throw new ArgumentException("GDEF format only supports single file compression.");
CompressFile(inputFiles[0], outputArchivePath);
}
else
{
throw new ArgumentException($"Unsupported archive format: {format}");
}
}

public void DecompressArchive(string inputArchivePath, string outputDirectory)
{
string format = Path.GetExtension(inputArchivePath);
if (format.Equals(".zip", StringComparison.OrdinalIgnoreCase))
{
var archiveManager = new ArchiveManager();
archiveManager.ExtractZipArchive(inputArchivePath, outputDirectory, DecompressFile);
}
else if (format.Equals(".gdef", StringComparison.OrdinalIgnoreCase))
{
string outputFileName = Path.GetFileNameWithoutExtension(inputArchivePath);
string outputFilePath = Path.Combine(outputDirectory, outputFileName);
DecompressFile(inputArchivePath, outputFilePath);
}
else
{
throw new ArgumentException($"Unsupported archive format: {format}");
}
}

// Simulation mode methods
private void CompressFileSimulation(string inputFile, string outputFile)
{
Expand Down
17 changes: 17 additions & 0 deletions GDeflateConsole/Kernel32.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Runtime.InteropServices;

namespace GDeflateConsole
{
internal static class Kernel32
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool FreeLibrary(IntPtr hModule);
}
}
Loading
Loading