TorchSharp Exception with GPU - c#

In my codebase I use TorchSharp to train a regression model. When using the CPU everything works fine, just when using the GPU i get a KeyNotFoundException at the optimizer.step() method call.
I have extracted the code into an example program that can be used to reproduce the problem.
It seems to have to do something with the custom CancelOut module and its weight parameters. If I remove it from the Sequential module the exception does not happen.
I am wondering if I am doing something wrong or if this is a TorchSharp bug that only occurs with GPU training, since CPU training works fine.
Here is the code:
using TorchSharp;
using TorchSharp.Modules;
using TorchSharp.Utils;
using static TorchSharp.torch.nn;
var module = Sequential(
new CancelOut(10),
Linear(10, 1)
);
var x = Enumerable.Range(0, 100).Select(x => new float[10]).ToArray();
var y = new float[100];
var trainer = new RegressionTorchTrainer(module, x, y, device: torch.CUDA);
trainer.Train();
public class CancelOut : Module
{
private readonly Parameter weights;
public CancelOut(int size) : base(nameof(CancelOut))
{
weights = Parameter(torch.zeros(size) + 4);
RegisterComponents();
}
public override torch.Tensor forward(torch.Tensor x)
{
return (x * torch.sigmoid(weights));
}
}
public class RegressionTorchTrainer : IDisposable
{
private readonly torch.Device? device;
private readonly torch.nn.Module module;
private readonly torch.Tensor xt;
private readonly torch.Tensor yt;
private readonly torch.Tensor wt;
public RegressionTorchTrainer(torch.nn.Module module, float[][] x, float[] y, float[]? weight = null, torch.Device? device = null)
{
this.device = device;
this.module = module;
xt = torch.tensor(x.SelectMany(x => x).ToArray(), x.Length, x[0].Length, device: this.device);
yt = torch.tensor(y, device: this.device);
wt = weight != null ? torch.tensor(weight, device: this.device) : torch.ones(y.Length, device: device);
}
public void Train(int iterations = 100, int batchSize = 128, double learningRate = 0.001, torch.optim.Optimizer? optimizer = null, long? seed = null)
{
if (seed != null)
torch.random.manual_seed(seed.Value);
var disposeOptimizer = optimizer == null;
optimizer ??= torch.optim.SGD(module.parameters(), learningRate);
var criterion = torch.nn.functional.mse_loss(torch.nn.Reduction.None);
if (device != null)
module.to(device);
module.train();
for (int iter = 0; iter < iterations; iter++)
{
using var permutation = torch.randperm(xt.size(0), device: device);
for (int i = 0; i < xt.size(0); i += batchSize)
{
using var indices1 = torch.arange(i, Math.Min(i + batchSize, xt.size(0)), device: device);
using var indices2 = permutation.index_select(0, indices1);
using var xb = xt.index_select(0, indices2);
using var yb = yt.index_select(0, indices2);
using var wb = wt.index_select(0, indices2);
using var prediction = module.forward(xb).view(-1);
using var loss = criterion(prediction, yb);
using var wloss = loss * wb;
using var mloss = wloss.mean();
optimizer.zero_grad();
mloss.backward();
optimizer.step();
GC.Collect(0);
}
}
if (disposeOptimizer)
optimizer.Dispose();
}
public void Dispose()
{
xt.Dispose();
yt.Dispose();
GC.SuppressFinalize(this);
}
}
public class RegressionTorchModel : IDisposable
{
private readonly torch.Device? device;
private readonly torch.nn.Module module;
private readonly bool ownsModule;
public RegressionTorchModel(torch.nn.Module module, bool ownsModule = true, torch.Device? device = null)
{
this.device = device;
this.module = module;
this.ownsModule = ownsModule;
}
public float Predict(float[] x)
{
module.to(device).eval();
using var xt = torch.tensor(x, device: device);
using var prediction = module.forward(xt);
using var predictionCpu = prediction.cpu();
return predictionCpu.item<float>();
}
public float[] Predict(float[][] x)
{
module.to(device).eval();
using var xt = torch.tensor(x.SelectMany(x => x).ToArray(), x.Length, x[0].Length, device: device);
using var prediction = module.forward(xt);
using var predictionCpu = prediction.cpu();
using var accessor = new TensorAccessor<float>(predictionCpu);
return accessor.ToArray();
}
public static RegressionTorchModel Load(string filename, torch.Device? device = null)
=> new(torch.nn.Module.Load(filename), true, device);
public void Save(string filename)
=> module.Save(filename);
public void Dispose()
{
if (ownsModule)
module.Dispose();
}
}

Related

How I can start multiple download async in c#

my problem is the following: I just want to run x requests at the same time depending on the user.
Well, it seems to work fine when the MaxConcurrentDownloads variable is equal to 1, but when I increase it, say 10: I have to wait for the 10taches to finish for it to execute so that Console.WriteLine as to write, when it's supposed to run asynchronously, right?
Can you help me? Here is a minimalist version of my "problem" (Also I want to specify that I have no compiler or syntax errors)
main.c
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace test_client
{
class Program
{
private static client cli = new client();
private static readonly string PATH = #Directory.GetCurrentDirectory();
private static int concurrency = 100;
private static async Task<bool> MakeJOB(int pos)
{
return await cli.NewRequest<bool>((HttpClient client)=>
{
try
{
HttpClientHandler handler = null;
if (cli.handler != null)
handler = cli.GethandlerIndexed(pos);
client = new HttpClient(handler);
cli.AssignDefaultHeaders(client);
using (HttpResponseMessage response = client.GetAsync("https://api.my-ip.io/ip.txt").Result)
using (HttpContent content = response.Content)
Console.WriteLine(content.ReadAsStringAsync().Result + " / " + Task.CurrentId);
return true;
}
catch { /* exception .. */ return false; }
});
}
static void Main(string[] args)
{
ServicePointManager.DefaultConnectionLimit = 100;
MainAsync(args).GetAwaiter().GetResult();
Console.ReadLine();
}
static async Task MainAsync(string[] args)
{
cli.SetConcurrentDownloads(concurrency);
var t = new Task[concurrency];
int pos = 0;
for (int i = 0; i < t.Length; i++, pos++)
t[i] = MakeJOB(pos++);
await Task.WhenAll(t);
}
}
}
client.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Http;
using System.Collections.Concurrent;
using System.Threading;
namespace test_client
{
public class client
{
private readonly ConcurrentDictionary<string, HttpClient> Clients;
public SemaphoreSlim Locker;
private CancellationTokenSource TokenSource = new CancellationTokenSource();
public HttpClientHandler[] handler { get; set; }
public string[] address { get; set; }
public string[] port { get; set; }
public string[] username { get; set; }
public string[] password { get; set; }
public int MaxConcurrentDownloads { get; set; }
private void initializeHandler(string address = "", string port = "", string user = "", string pass = "")
{
initializeHandler(new string[] { string.Concat(address, ":", port, ":", user, ":", pass) });
}
private void initializeHandler(string[] proxies_client)
{
if (proxies_client == null || proxies_client.Length == 0)
return;
this.address = new string[proxies_client.Length];
this.port = new string[proxies_client.Length];
this.username = new string[proxies_client.Length];
this.password = new string[proxies_client.Length];
for (int i = 0; i < proxies_client.Length; i++)
{
var split = proxies_client[i].Split(new char[] { ':' });
this.address[i] = split[0] != "" ? split[0] : "";
this.port[i] = split[1] != "" ? split[1] : "";
this.username[i] = split[2] != "" ? split[2] : "";
this.password[i] = split[3] != "" ? split[3] : "";
}
var proxies = new WebProxy[proxies_client.Length];
NetworkCredential[] credential = new NetworkCredential[proxies_client.Length];
for (int i = 0; i < proxies_client.Length; i++)
{
if (this.username[i] != "")
credential[i] = new NetworkCredential(this.username[i], this.password[i]);
else
credential[i] = CredentialCache.DefaultNetworkCredentials;
}
const string protocol = "http://";
for (int i = 0; i < proxies.Length; i++)
{
if (this.address[i] != "")
{
var uri = proxies_client[i].Split(new char[] { ':' });
if (!uri[0].Contains(protocol))
uri[0] = string.Concat(protocol, uri[0]);
proxies[i] = new WebProxy()
{
Address = new Uri(string.Concat(uri[0], ":", uri[1])),
Credentials = credential[i],
};
}
};
this.handler = new HttpClientHandler[proxies.Length];
for (int i = 0; i < proxies.Length; i++)
{
if (proxies[i].Address.AbsoluteUri != "")
this.handler[i] = new HttpClientHandler() { Proxy = proxies[i] };
else
this.handler[i] = new HttpClientHandler();
}
}
public HttpClientHandler GethandlerIndexed(int index)
{
return (this.handler[index % this.handler.Length]);
}
public void SetConcurrentDownloads(int nb = 1)
{
Locker = new SemaphoreSlim(nb, nb);
}
public client(string[] proxies = null)
{
Clients = new ConcurrentDictionary<string, HttpClient>();
if (Locker is null)
Locker = new SemaphoreSlim(1, 1);
if (proxies != null)
initializeHandler(proxies);
}
private async Task<HttpClient> CreateClient(string Name, bool persistent, CancellationToken token)
{
if (Clients.ContainsKey(Name))
return Clients[Name];
HttpClient newClient = new HttpClient();
if (persistent)
{
while (Clients.TryAdd(Name, newClient) is false)
{
token.ThrowIfCancellationRequested();
await Task.Delay(1, token);
}
}
return newClient;
}
public async Task<T> NewRequest<T>(Func<HttpClient, T> Expression, int? MaxTimeout = 2000, string Id = null)
{
await Locker.WaitAsync(MaxTimeout ?? 2000, TokenSource.Token);
bool persistent = true;
if (Id is null)
{
persistent = false;
Id = string.Empty;
}
try
{
HttpClient client = await CreateClient(Id, persistent, TokenSource.Token);
T result = await Task.Run<T>(() => Expression(client), TokenSource.Token);
if (persistent is false)
client?.Dispose();
return result;
}
finally
{
Locker.Release();
}
}
public void AssignDefaultHeaders(HttpClient client)
{
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
//client.Timeout = TimeSpan.FromSeconds(3);
}
public async Task Cancel(string Name)
{
if (Clients.ContainsKey(Name))
{
CancellationToken token = TokenSource.Token;
HttpClient foundClient;
while (Clients.TryGetValue(Name, out foundClient) is false)
{
token.ThrowIfCancellationRequested();
await Task.Delay(1, token);
}
if (foundClient != null)
{
foundClient?.Dispose();
}
}
}
public void ForceCancelAll()
{
TokenSource?.Cancel();
TokenSource?.Dispose();
TokenSource = new CancellationTokenSource();
foreach (var item in Clients)
{
item.Value?.Dispose();
}
Clients.Clear();
}
}
}
One thing I spotted in a quick skim: Your line in main.cs::Program.MakeJOB:
using (HttpResponseMessage response = client.GetAsync("https://api.my-ip.io/ip.txt").Result)
should instead read
using (HttpResponseMessage response = await client.GetAsync("https://api.my-ip.io/ip.txt"))
This may not be your only issue, but by not awaiting the GetAsync method, you are effectively blocking on the request rather than yielding control back to the caller so that it can, for instance, context switch between tasks or queue up other tasks.
Same goes for
Console.WriteLine(content.ReadAsStringAsync().Result + " / " + Task.CurrentId);
which should be
Console.WriteLine((await content.ReadAsStringAsync()) + " / " + Task.CurrentId);
Although that one is not likely to block for a significant amount of time.

How to migrate custom TokenFilter from Lucene.Net 3.0.3 to 4.8

I have the following custom TokenFilter that works on Lucene.Net 3.0.3 and I need to migrate it to Lucene.Net 4.8:
public sealed class AccentFoldingFilter : TokenFilter
{
private ITermAttribute termAttribute;
public AccentFoldingFilter(TokenStream input) : base(input)
{
termAttribute = this.input.GetAttribute<ITermAttribute>();
}
public override bool IncrementToken()
{
if (this.input.IncrementToken())
{
termAttribute.SetTermBuffer(termAttribute.Term.RemoveDiacritics());
return true;
}
return false;
}
}
ITermAttribute no longer exists, I guess I need to use ICharTermAttribute but I don't know how to do it.
How to do the same in 4.8?
For reference this is the RemoveDiacritics extension method:
public static string RemoveDiacritics(this string text)
{
var normalizedString = text.Normalize(NormalizationForm.FormD);
var stringBuilder = new StringBuilder();
foreach (var c in normalizedString)
{
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
if (unicodeCategory != UnicodeCategory.NonSpacingMark)
{
stringBuilder.Append(c);
}
}
return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
}
Although you could use the answer below, do note that Lucene.NET 4.8.0 includes a ICUNormalizer2Filter, an ICUNormalizer2CharFilter, and an ICUFoldingFilter in the box. However, you may still be inclined to use your existing solution rather than drag in a 20MB+ dependency (ICU4N).
To translate you will need to add the ICharTermAttribute to your filter directly (not on the TokenStream). The attribute will be pulled out of the shared context of the token stream by calling GetAttribute<ICharTermAttribute>().
public sealed class AccentFoldingFilter : TokenFilter
{
private ICharTermAttribute termAttribute;
public AccentFoldingFilter(TokenStream input) : base(input)
{
termAttribute = this.GetAttribute<ICharTermAttribute>();
}
public override bool IncrementToken()
{
if (this.m_input.IncrementToken())
{
string buffer = termAttribute.ToString().RemoveDiacritics();
termAttribute.SetEmpty().Append(buffer);
return true;
}
return false;
}
}
Also, the RemoveDiacritics method implementation doesn't account for surrogate pairs, which could lead to hard to diagnose bugs down the road.
public static string RemoveDiacritics(this string text)
{
var normalizedString = text.Normalize(NormalizationForm.FormD);
int inputLength = normalizedString.Length;
char[] buffer = new char[inputLength];
// TODO: If the strings are short (less than 256 chars),
// consider using this (must be unsafe context)
// char* buffer = stackalloc char[inputLength];
int bufferLength = 0;
for (int i = 0; i < inputLength;)
{
// Handle surrogate pairs
int charCount = char.IsHighSurrogate(normalizedString, i)
&& i < inputLength - 1
&& char.IsLowSurrogate(normalizedString, i + 1) ? 2 : 1;
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(normalizedString, i);
if (unicodeCategory != UnicodeCategory.NonSpacingMark)
{
buffer[bufferLength++] = normalizedString[i]; // high surrogate / BMP char
if (charCount == 2)
{
buffer[bufferLength++] = normalizedString[i + 1]; // low surrogate
}
}
i += charCount;
}
return new string(buffer, 0, bufferLength).Normalize(NormalizationForm.FormC);
}

(C# VB) Could I change all variables' values in a class dynamically?

I've seen ways to list all variables in a certain class, but is there a way to set their values?
I want a method I can call, and it can reset all variables' values to false / 0 , I know I can manually set those to false / 0, but any change to their values would mess up everything, and I'm just seeing if there's anything more dynamic / easy way that this could be done ?
Currently I'm doing the following:
// These are just some of the vars that are here.
Error = false;
double GUM = 0, MUM = 0;
decimal Mass = 0, GAcc = 0, Fg = 0, FµsRes = 0, FµkRes = 0, Fµs = FµsNS.Value, Fµk = FµkNS.Value;
As others have mentioned, you could use Reflection to set all the class fields to their default values:
using System;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
myClass.Error = true;
myClass.GUM = 1;
myClass.MUM = 2;
myClass.Mass = 3.5m;
myClass.GAcc = 4.5m;
myClass.Fg = 5.5m;
ResetFields(myClass);
// All fields are reseted
}
public static void ResetFields(object source)
{
foreach (var fieldInfo in source.GetType().GetFields() )
{
fieldInfo.SetValue(source, GetDefault(fieldInfo.FieldType) );
}
}
public static object GetDefault(Type type)
{
if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
}
public class MyClass
{
public bool Error = false;
public double GUM = 0, MUM = 0;
public decimal Mass = 0, GAcc = 0, Fg = 0;
//etc etc
}
}
A better approach however, is to create a class to only hold the values and re-create it when needed:
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
myClass.Variables = new MyVariables();
myClass.Variables.Error = true;
myClass.Variables.GUM = 1;
myClass.Variables.MUM = 2;
myClass.Variables.Mass = 3.5m;
myClass.Variables.GAcc = 4.5m;
myClass.Variables.Fg = 5.5m;
myClass.Variables = new MyVariables();
// All fields are reseted
}
}
public class MyVariables
{
public bool Error = false;
public double GUM = 0, MUM = 0;
public decimal Mass = 0, GAcc = 0, Fg = 0;
}
public class MyClass
{
public MyVariables Variables;
// etc etc
public int Xyz
{
get { return Variables.GUM + Variables.MUM; } // Use calculated properties
}
}
}
The GetDefault method is shown in this answer.

How to keep data for different guilds/servers for Discord Bots

I am currently undertaking a project in which I am trying to make a RPG for a discord bot. I am currently struggling with how to implement a way to keep data for different servers separate. For example, I'm trying to store the location of the party for each server. I have tried testing moving from 'town' to 'forest'. It works on the server that the command is used, but all other servers that the bot is on also have their location updated to 'forest'. Since I'm new to c# as well I am struggling to work out a way to keep the location being updated on each server.
A possible solution would be to store an object for each guild in an array and reference it whenever guild specific data is required, however this doesn't seem like an elegant solution.
What would be the best way to achieve data separation between guilds?
MAIN
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TestBot2.Modules;
namespace TestBot2
{
class Program
{
static void Main(string[] args){
new Program().RunBotAsync().GetAwaiter().GetResult();
}
private DiscordSocketClient _client;
private CommandService _command;
private IServiceProvider _service;
public async Task RunBotAsync()
{
_client = new DiscordSocketClient();
_command = new CommandService();
_service = new ServiceCollection()
.AddSingleton(_client)
.AddSingleton(_command)
.BuildServiceProvider();
string botToken = *** BOT TOKEN ***;
//event subscription
_client.Log += Log;
await RegisterCommandAsync();
await _client.LoginAsync(TokenType.Bot, botToken);
await _client.StartAsync();
await Task.Delay(-1);
}
private Task Log(LogMessage arg)
{
Console.WriteLine(arg);
return null;
}
public async Task RegisterCommandAsync()
{
_client.MessageReceived += HandleCommandAsync;
await _command.AddModulesAsync(Assembly.GetEntryAssembly());
}
private async Task HandleCommandAsync(SocketMessage arg)
{
var message = arg as SocketUserMessage;
if (!(message is SocketUserMessage) || message.Author.IsBot) {
return;
}
int argPos = 1;
if (message.HasStringPrefix("cf!", ref argPos) || message.HasMentionPrefix(_client.CurrentUser, ref argPos))
{
var context = new SocketCommandContext(_client, message);
var result = await _command.ExecuteAsync(context, argPos+1, _service);
if (!result.IsSuccess)
Console.WriteLine(result.ErrorReason);
}
}
}
}
UTILITY
static string location = "town"; //curent loc
static string[] locations = //array of vlaid loc
{
"town", "forest"
};
int[,] travelMtx = new int[,] //distance matrix
{
{0,2 },
{2,0 }
};
public string D6()
{
Random rnd = new Random();
string reply;
reply = Convert.ToString(rnd.Next(1, 7));
return reply;
}
public string charName(string charowner = "")
{
string charname;
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();
conn.ConnectionString = [FILE LOCATION]
conn.Open();
String my_query = "SELECT CharName FROM Chars WHERE CharOwner='" + charowner + "'";
Console.WriteLine(my_query);
OleDbCommand cmd = new OleDbCommand(my_query, conn);
charname = (string)cmd.ExecuteScalar();
Console.Write(charname);
return charname;
}
public string usermention(string user = "")
{
return user;
}
public string getLoc()
{
return Utility.location;
}
public void setLoc(string location)
{
Utility.location = location;
}
public bool checkLoc(string dest)
{
for (int i = 0; i < locations.Length; i++)
{
if (dest.ToLower() == locations[i])
{
return true;
}
}
return false;
}
public int travelTime(string location, string dest)
{
int x = 0;
int y = 0;
for (int i = 0; i < locations.Length; i++)
{
if (location.ToLower() == locations[i])
{
x = i;
}
if (dest.ToLower() == locations[i])
{
y= i;
}
}
return travelMtx[x,y];
}
}
}
TRAVEL
public class Travel : ModuleBase<SocketCommandContext>
{
[Command("Travel")]
public async Task PingAsync(string dest = "")
{
Utility Util = new Utility();
string loc = Util.getLoc();
int travelTime = 0;
if (Util.checkLoc(dest) == true)
{
travelTime = Util.travelTime(loc, dest);
}
Util.setLoc(dest);
await ReplyAsync("you are now in " + dest + " it took " + travelTime + " days" );
}
}
}
I think you could try to store it together with the serverip, so that you can ask for CharOwner='" + charowner + "'" and ServerIp='" + serverip + "'" in you WHERE part of the sql.
It's just a guess, but maybe it works. :)

Telegram API Code

please Help us,
Telegram API code :
messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
---functions---
messages.getDialogs#eccf1df6 offset:int max_id:int limit:int = messages.Dialogs;
how i can make class for this ? - using TLSharp;
i have this class in Request folder ( from TLSharp );
how i can edit this class or create new class and work with Telegram API method ? ( telegram API is very Unclear for we )
using System;
using System.Collections.Generic;
using System.IO;
using TLSharp.Core.MTProto;
namespace TLSharp.Core.Requests
{
class GetHistoryRequest : MTProtoRequest
{
InputPeer _peer;
int _offset;
int _max_id;
int _limit;
public List<Message> messages;
public List<Chat> chats;
public List<User> users;
public GetHistoryRequest(InputPeer peer, int offset, int max_id, int limit)
{
_peer = peer;
_offset = offset;
_max_id = max_id;
_limit = limit;
}
public override void OnSend(BinaryWriter writer)
{
writer.Write(0x92a1df2f);
_peer.Write(writer);
writer.Write(_offset);
writer.Write(_max_id);
writer.Write(_limit);
}
public override void OnResponse(BinaryReader reader)
{
bool messagesSlice = reader.ReadUInt32() == 0xb446ae3; // else messages#8c718e87
if (messagesSlice) reader.ReadInt32(); // count
// messages
var result = reader.ReadUInt32(); // vector#1cb5c415
int messages_len = reader.ReadInt32();
messages = new List<Message>(messages_len);
for (var i = 0; i < messages_len; i++)
{
var msgEl = TL.Parse<Message>(reader);
messages.Add(msgEl);
}
// chats
reader.ReadUInt32();
int chats_len = reader.ReadInt32();
chats = new List<Chat>(chats_len);
for (int i = 0; i < chats_len; i++)
chats.Add(TL.Parse<Chat>(reader));
/*
// users
reader.ReadUInt32();
int users_len = reader.ReadInt32();
users = new List<User>(users_len);
for (int i = 0; i < users_len; i++)
users.Add(TL.Parse<User>(reader));
*/
}
public override void OnException(Exception exception)
{
throw new NotImplementedException();
}
public override bool Confirmed => true;
public override bool Responded { get; }
}
}

Categories

Resources