Does anyone had ever successfully utilized CUDAfy in VB.NET? - vb.net

I´m trying to utilize CUDAFy 1.29 in VB.NET using VS2013.
I´m trying to translate the samples of C# from CUDAFy and I´m having two type of errors, like explained below:
My Variables
Shared cs_CC As String = "adiciona"
Shared MyGPU As GPGPU = Nothing
Shared Arch As eArchitecture = Nothing
My Code:
Shared Executa()
if Loader = true
Dim Modulo = CudafyModule.TryDeserialize(cs_cc)
If IsNothing(Modulo) OrElse (Not Modulo.TryVerifyChecksums) Then
Modulo = CudafyTranslator.Cudafy(ePlatform.All, Arch, cs_CC.GetType)
Modulo.Serialize()
End If
MyGPU.Loadmodule(Modulo)
Dim a As Integer() = New Integer(N - 1) {}
Dim b As Integer() = New Integer(N - 1) {}
Dim c As Integer() = New Integer(N - 1) {}
' allocate the memory on the GPU
Dim dev_a As Integer() = MyGPU.Allocate(Of Integer)(a)
Dim dev_b As Integer() = MyGPU.Allocate(Of Integer)(b)
Dim dev_c As Integer() = MyGPU.Allocate(Of Integer)(c)
' fill the arrays 'a' and 'b' on the CPU
For i As Integer = 0 To N - 1
a(i) = i
b(i) = 2 * i
Next
' copy the arrays 'a' and 'b' to the GPU
MyGPU.CopyToDevice(a, dev_a)
MyGPU.CopyToDevice(b, dev_b)
For i As Integer = 0 To 128
MyGPU.Launch(1, 1).adiciona(dev_a, dev_b, dev_c)
Next
end if
End Sub
The function ADICIONA which would run on CUDA
<Cudafy()> _
Shared Sub adiciona(thread As GThread, a As Integer(), b As Integer(), c As Integer())
Dim tid As Integer = thread.blockIdx.x
While tid < N
c(tid) = a(tid) + b(tid)
tid += thread.gridDim.x
End While
End Sub
LOADER: try to identify card and CUDA (successfully running):
Public Shared Function Loader() As Boolean
DeviceType = eGPUType.Cuda
CudafyModes.Target = DeviceType
CudafyTranslator.Language = If(CudafyModes.Target = eGPUType.Cuda, eLanguage.Cuda, eLanguage.OpenCL)
Dim CompatibleDevice As GPGPUProperties() = CudafyHost.GetDeviceProperties(CudafyModes.Target, True).ToArray
If Not CompatibleDevice.Any Then ' não possui um full-CUDA device
MsgBox("I do not found any OpenCL or CUDA compatible device")
Return False
End If
Dim selectedDevice As GPGPUProperties = CompatibleDevice(0)
If IsNothing(selectedDevice) Then
MsgBox("I cannot allocate a compatible device")
Return False
End If
CudafyModes.DeviceId = selectedDevice.DeviceId
Thread_per_Block = selectedDevice.MaxThreadsPerBlock
Blocks_per_Grid = selectedDevice.MaxThreadsSize.x
Shared_Mem_per_Block = selectedDevice.SharedMemoryPerBlock
MyGPU = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId)
Arch = MyGPU.GetArchitecture
Return True
End Function
The problems:
Problem 1: If I utilize just dim Modulo as CudafyModule = CudafyTranslator.Cudafy() I get the following error: Checked Statements are not supported. It´s weird! All documentation of Cudafy shows this line exactly as it!
Problem 2: So, I try to check the existence of a written module (.CDFY) and, if does not exist, I call the Serialize() function. The problem is the function creates a file called STRING.CDFY in my folder, but not the ADICIONA.CDFY nor ADD_LONG_LOOP.CDFY, which would be correct. Since I would like to avoid compilation at every run of this code, how to correctly make CUDAFy to write it?
Problem 3: When VS runs, everything goes OK until the point of calling ADICIONA (MyGPU.Launch)! VS stops the execution with a message "COULD NOT FIND FUNCTION 'ADICIONA' IN MODULE".
Interesting to notice that:
1- both temporary files are created (.CU, .PTX) and also the .CDFY file. It evidences the NVCC compiler is running well and creating the CUDA modules. So, why the code is NOT finding the function ADICIONA?
2- All samples written in C# run here 100%. And the conversion from C# and VB seems to be OK (I had utilized TELERIK to do it). I don´t guess the problem may be related to this, but I may be wrong.
3- The problem is NOT related to neither with NVCC compiler nor some reference into VB.NET, since the code compiles.
I tried to write in CODEPLEX for an answer. No answers at all...
I tried to see a lot of samples in Internet, but ALL OF THEM are created to CUDAFy C# and none of them are utilizing version 1.29 and CUDA 7.5.
Also, I would like to understand WHY the basic function (CudafyTranslator.Cudafy()) get an error in VB but not in C#.
So, does anyone here had successfully created a CUDAFy code using VB.NET?
Thank you VERY much for any help.

To solve Problem 1, check "Remove integer overflow checks" under Project Properties > Compile > Advanced Compile Options > Optimizations. More info: http://forums.asp.net/post/715302.aspx

Try this simple example:
Imports Cudafy
Imports Cudafy.Host
Imports Cudafy.Translator
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim GPU As GPGPU = CudafyHost.GetDevice(eGPUType.OpenCL, CudafyModes.DeviceId)
Dim Modulo As CudafyModule = CudafyTranslator.Cudafy(ePlatform.All, GPU.GetArchitecture())
GPU.LoadModule(Modulo)
Dim Resultado As Integer
Dim ResultadoGPU As Integer() = gpu.Allocate(Of Integer)()
GPU.Launch().Adicionar(2, 7, ResultadoGPU)
GPU.CopyFromDevice(ResultadoGPU, Resultado)
MessageBox.Show("2 + 7 = " & Resultado)
GPU.Launch().Subtrair(2, 7, ResultadoGPU)
GPU.CopyFromDevice(ResultadoGPU, Resultado)
MessageBox.Show("2 - 7 = " & Resultado)
GPU.Free(ResultadoGPU)
End Sub
<Cudafy()>
Private Shared Sub Adicionar(a As Integer, b As Integer, c As Integer())
c(0) = a + b
End Sub
<Cudafy()>
Private Shared Sub Subtrair(a As Integer, b As Integer, c As Integer())
c(0) = a - b
End Sub
End Class

Related

Does VB.NET have pattern matching like C# does?

Not too long ago C# added a nice "pattern matching" feature where you can check an object's type and cast it to that type all in one statement:
object o = GetSomeObjectFromTheDatabase();
if (o is Person p)
{
Console.WriteLine($"{p.Name} is {p.Age} years old.");
}
Does VB.NET have anything like this, or will I have to do the type check and cast in two separate operations as I have in the past?
As I had previously noted in my own comment (and Codexer noted in the previous answer), this feature is not in VB.
Based on recent comments from Microsoft (https://devblogs.microsoft.com/vbteam/visual-basic-support-planned-for-net-5-0/) it doesn't seem likely that this feature will be added to the language in the near future. That having been said, the language still has a very full set of features that is missing very little for day-to-day development. If you're considering whether to do further development in VB, you would consider availability of development resources (internally and externally), suitability of VB for your project, and your current code base.
The .TryCast might be what you are looking for. If it succeeds, it will make the assignment, otherwise it returns Nothing. To test I just commented out one of the 2 Return statements. Note that the underlying type is Coffee if c is returned.
Private Function GetSomeObjectFromTheDatabase() As Object
Dim dt = LoadCoffeeTable() 'Returns a DataTable
Dim c = New Coffee(CInt(dt(0)(0)), dt(0)(1).ToString, dt(0)(2).ToString)
'Return c
Return "I am not a Coffee"
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim o As Object = GetSomeObjectFromTheDatabase()
Dim p As Coffee = TryCast(o, Coffee)
If p Is Nothing Then
MessageBox.Show("Object is not a Coffee " & o.ToString)
Else
MessageBox.Show(p.Name)
End If
End Sub
Unfortunately VB doesn't have pattern matching as mentioned already in the comments. One option is to create a module so we can create an extension to use on anything we would need to type match.
Imports System.Runtime.CompilerServices
Module Extensions
<Extension()>
Public Function IsPatternMatch(Of T)(MyObj As Object, ByRef outObj As T) As Boolean
Dim isMatch As Boolean = TypeOf MyObj Is T
outObj = If(isMatch, CType(MyObj, T), outObj)
Return isMatch
End Function
End Module
Example Usage:
Dim o As Object = Nothing
Dim p As Person = Nothing
o = GetSomeObjectFromTheDatabase()
If o.IsPatternMatch(p) Then
' Do something with p now...
End If

VBCodeProvider Can not cast correctly the Implicit Variable declaration on compile

I am Compiling My string Code(I read My Code from Text File) In vb and it works fine but i have a function that returns nullable double(Double?)
when i use it like this
Dim x As Double? = Myfunc(1000) 'it returns Nothing
my x variable fills with Nothing and it's ok
But When I use it like this
Dim x = Myfunc(1000) 'it returns Nothing
my x value is 0 !!!!
How can i solve this problem
i want my users write codes like first code block
i tested all Option Explicit and Option Strict but it did not gain me anything.
please let me know how can i use Just dim x not Dim x as (type)
thank you for your helps
UPDATE :this is Myfunc Code :
Function Myfunc(parameterId As Long) As Double?
If parameterId = 1000 Then
Return Nothing
Else
Return tot(parameterId) 'it is a dictionary of values
End If
End Function
And this Is my Compile Class :
Private Shared Function Compile(ByVal vbCode As String) As CompilerResults
Dim providerOptions = New Dictionary(Of String, String)
providerOptions.Add("CompilerVersion", "v4.0")
' Create the VB.NET compiler.
Dim vbProv = New VBCodeProvider(providerOptions)
' Create parameters to pass to the compiler.
Dim vbParams = New CompilerParameters()
' Add referenced assemblies.
vbParams.ReferencedAssemblies.Add("mscorlib.dll")
vbParams.ReferencedAssemblies.Add("System.Core.dll")
vbParams.ReferencedAssemblies.Add("System.dll")
vbParams.ReferencedAssemblies.Add("System.Windows.Forms.dll")
vbParams.ReferencedAssemblies.Add("System.Data.dll")
vbParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
vbParams.ReferencedAssemblies.Add("System.Xml.dll")
vbParams.ReferencedAssemblies.Add("System.Xml.Linq.dll")
vbParams.GenerateExecutable = False
' Ensure we generate an assembly in memory and not as a physical file.
vbParams.GenerateInMemory = True
' Compile the code and get the compiler results (contains errors, etc.)
Return vbProv.CompileAssemblyFromSource(vbParams, vbCode)
End Function
As discussed above, Option Infer On needs to be included to force the compiler to create the variable as the required type - in this case the Double? returned by MyFunc.

CovrageInfo.CreateFromFile is giving an error

I have replicated the code from the example to collect the result for code coverage from Here except that my code is vb.net
Here is my code
Imports Microsoft.VisualStudio.Coverage.Analysis
Module Module1
Sub Main()
Using info As CoverageInfo = CoverageInfo.CreateFromFile("C:MyFile\data.coverage")
Dim lines As New List(Of BlockLineRange)()
For Each [module] As ICoverageModule In info.Modules
Dim coverageBuffer As Byte() = [module].GetCoverageBuffer(Nothing)
Using reader As ISymbolReader = [module].Symbols.CreateReader()
Dim methodId As UInteger = 0
Dim MethodName As String = ""
Dim undecoratedMethodName As String = ""
Dim ClassName As String = ""
Dim NameSpaceName As String = ""
lines.Clear()
While reader.GetNextMethod(methodId, MethodName, undecoratedMethodName, ClassName, NameSpaceName, lines)
Dim stats As CoverageStatistics = CoverageInfo.GetMethodStatistics(coverageBuffer, lines)
Console.WriteLine("Method {0}{1}{2}{3}{4} has:" & NameSpaceName & ClassName & undecoratedMethodName)
Console.WriteLine(" blocks covered are {0}", stats.BlocksCovered)
End While
End Using
Next
End Using
End Sub
End Module
When I run this on the line for CreateFromFile i get a ImageNotFoundException
Image File "C:\SomeAddress\MyServer\UnitTest.dll" could not be found
I have already as per instructions added the neccessary dlls to my project copied and the other 2 as references.
And yet another tumbleweed moment....
Basically the problem was that folder containing my coverage file also had to contains all the dlls used within that assembely that tests were ran on in order to create that object.
hope this helps you if you ever stumbled over this issuen :)

Threading Exception: The number of WaitHandles must be less than or equal to 64

The title is to make this easy to find for others having this error. I'm new to Threading, so this is really giving me heck. I'm getting this runtime error that crashed Cassini. This is code that I'm maintaining originally developed as a website project in VS 2003 and converted to a VS 2008 website project.
Important Info:
The number of objects in the manualEvents array is 128 in this case.
products is an array of Strings
Need to support .NET 2.0
For Each product As String In products
If Not product.Trim().ToUpper().EndsWith("OBSOLETE") Then
calls += 1
End If
Next
Dim results(calls - 1) As DownloadResults
'Dim manualEvents(calls - 1) As Threading.ManualResetEvent '128 objects in this case.
Dim manualEvents(0) As Threading.ManualResetEvent
manualEvents(0) = New Threading.ManualResetEvent(False)
'NOTE: I don't think this will work because what is not seen here, is that
' this code is being used to populate and cache a long list of products,
' each with their own category, etc. Am I misunderstanding something?
'initialize results structures
'spawn background workers
calls = 0
For Each product As String In products
If Not product.Trim().ToUpper().EndsWith("OBSOLETE") Then
Dim result As New DownloadResults
'manualEvents(calls) = New Threading.ManualResetEvent(False)
'Moved above For Each after declaration of variable
result.params.product = product
result.params.category = docType
'result.ManualEvent = manualEvents(calls)
result.ManualEvent = manualEvents(0)
result.Context = Me._context
results(calls) = result
Threading.ThreadPool.QueueUserWorkItem(AddressOf ProcessSingleCategoryProduct, results(calls))
Threading.Interlocked.Increment(calls) 'Replaces below incrementation
'calls += 1
End If
Next
Threading.WaitHandle.WaitAll(manualEvents) 'CRASHES HERE
Thread Helper Function (for the sake of completion)
Public Shared Sub ProcessSingleCategoryProduct(ByVal state As Object)
Dim drs As DownloadResults = CType(state, DownloadResults)
Dim adc As New cADCWebService(drs.Context)
drs.docs = adc.DownloadADC(drs.params.category, drs.params.product)
drs.ManualEvent.Set()
End Sub
You don't need an array of 128 manual events to check for completion of all 128 threads.
Create only one manual reset event and a plain integer starting at 128. Decrement that integer using Interlocked.Decrement at the end of ProcessSingleCategoryProduct, and only signal the event when the count reaches zero:
if (Interlocked.Decrement(ByRef myCounter) = 0) myEvent.Set();
Then declare only one Threading.ManualResetEvent as opposed to an array of them, and you can call WaitOne instead of WaitAll on it, and you are done.
See also usr's comment for an easier alternative in case you have .NET 4.

How can I get parallel extensions to run a function that has two input parameters?

I've tried really hard to get this to work and have had no luck. How can I get parallel extensions to run a function that has two input parameters? I'm using the more recent version, the Reactive Extensions with the 3.5 framework.
I need to get the extensions to run act (or the function ProcessOrder) but no matter what I try I can't get it to do it.
Dim act As New System.Action(Of Int32, Date)(AddressOf ProcessOrder)
act(CInt(RowA("ID")), RunDate)
Tasks.Task.Factory.StartNew(act)
I used to be able to do the following:
Dim A(0) As Object
A(0) = CInt(RowA("ID"))
A(1) = RunDate
Tasks.Task.Create(AddressOf ProcessOrder, A)
But it's not supported anymore
Create a small class that has the two parameters as properties and have a method on the class that acts upon those properties.
Public Class ProcessClass
Private _p1 As Integer
Private _p2 As Date
Public Sub New(ByVal p1 As Integer, ByVal p2 As Date)
Me._p1 = p1
Me._p2 = p2
End Sub
Public Sub ProcessOrder()
Trace.WriteLine(String.Format("{0}:{1}", _p1, _p2))
End Sub
End Class
And then invoke it by:
Dim Obj As New ProcessClass(1, DateTime.Now())
Dim Act As New System.Action(AddressOf Obj.ProcessOrder)
System.Threading.Tasks.Task.Factory.StartNew(Act)