dpdk19.11 ixgbe rx queue increase to 22 didn't not take effect, - rss

the original number of rx queue is 16,increase to 22,the increase queue can't receive packets.eth config as follows,I have print the reta table and queue seems setting are right.
static struct rte_eth_conf port_conf_def = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = RTE_ETHER_MAX_LEN,
.split_hdr_size = 0, /**< hdr buf size */
.offloads = DEV_RX_OFFLOAD_IPV4_CKSUM,
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = rss_intel_key,
.rss_key_len = 40,
.rss_hf = ETH_RSS_PROTO_MASK,
},
},
.txmode = {
.mq_mode = ETH_MQ_TX_NONE,
},
.fdir_conf = {
.mode = RTE_FDIR_MODE_PERFECT,
.pballoc = RTE_FDIR_PBALLOC_64K,
.status = RTE_FDIR_REPORT_STATUS/*_ALWAYS*/,
.mask = {
.vlan_tci_mask = 0x0,
.ipv4_mask = {
.src_ip = 0x00000000,
.dst_ip = 0x0,
},
.ipv6_mask = {
.src_ip = { 0, 0, 0, 0 },
.dst_ip = { 0, 0, 0, 0 },
},
.src_port_mask = 0x0000,
/* to be changed according to slave lcore number in use */
.dst_port_mask = RTE_BE16(0x00FF),
.mac_addr_byte_mask = 0x00,
.tunnel_type_mask = 0,
.tunnel_id_mask = 0,
},
.drop_queue = 127,
.flex_conf = {
.nb_payloads = 0,
.nb_flexmasks = 0,
},
},
};

Using DPDK sample programs like testpmd, skeleton, l2fwd we can increase the RX queue for Phsycial Function (PF) from 1 to 32 without any issues. NIC used for testing are Physical Intel Fortville and Columbiaville.
But for virtual NIC like PCAP, TAP and TUN this is not possible as max queue are intizliaed by OS and driver.
Note: requested multiple times to #IdeaWi for details on NIC, OS, and firmware. There are no updates .

Related

I m trying to list a class object inside a class object in asp.net webservice using c#

I have to define class data and make it a list. I have a ItemDetails class,i have to define it's datamembers in InvoiceRoot Class. When i'm defining it's data seperately it's working fine and making list. But when I do it insidethe class object of InvoiceRoot class,it doesn't work the for loop doesn't work. So How can I make the list of ItemDetails datamembers
Here I make the list by initializing the class object separately:
List<ItemDetails> ItemLists = new List<ItemDetails>();
for (int i = 0; i < serial_no; i++)
{
ItemLists.Add(new ItemDetails
{
SlNo = (string)All_SerialNo[i],
PrdDesc = null,
IsServc = item_isservice,
HsnCd = item_hsncode[i].ToString(),
Barcde = null,
Qty = Convert.ToDecimal(item_quantity[i].ToString()),
FreeQty = Convert.ToDecimal(item_freeqty[i].ToString()),
Unit = null,
UnitPrice = Convert.ToDecimal(item_rate[i].ToString()),
TotAmt = Convert.ToDecimal(item_total_price[i].ToString()),
Discount = Convert.ToDecimal(item_discount[i].ToString()),
PreTaxVal = Convert.ToDecimal(item_taxable_amount[i].ToString()),
AssAmt = Convert.ToDecimal(item_taxable_amount[i].ToString()) - Convert.ToDecimal(item_discount[i].ToString()),
GstRt = 9,
IgstAmt = Convert.ToDecimal(item_IGST_Amt[i].ToString()),
CgstAmt = Convert.ToDecimal(item_CGST_Amt[i].ToString()),
SgstAmt = Convert.ToDecimal(item_SGST_Amt[i].ToString()),
CesRt = 0,
CesAmt = 0,
OthChrg = 0,
StateCesRt = 0,
StateCesAmt = 0,
StateCesNonAdvlAmt = 0,
TotItemVal = item_totalvalue[i].ToString(),
OrdLineRef = null,
OrgCntry = null,
PrdSlNo = null,
BchDtls = null,
});
}
Here I am trying make the list inside the InvoiceRoot class object
InvoiceRoot invoice = new InvoiceRoot
{
Version = "1.1",
DocDtls = new DocumentDetails
{
Typ = "Invoice",
No = invoice_no.ToString(),
Dt = invoice_date
},
ItemList = new List<ItemDetails>
{
new ItemDetails
{
for (int i = 0; i < serial_no; i++)
{
ItemLists.Add(new ItemDetails
{
SlNo = (string)All_SerialNo[i],
PrdDesc = null,
IsServc = item_isservice,
HsnCd = item_hsncode[i].ToString(),
Barcde = null,
Qty = Convert.ToDecimal(item_quantity[i].ToString()),
FreeQty = Convert.ToDecimal(item_freeqty[i].ToString()),
Unit = null,
UnitPrice = Convert.ToDecimal(item_rate[i].ToString()),
TotAmt = Convert.ToDecimal(item_total_price[i].ToString()),
Discount = Convert.ToDecimal(item_discount[i].ToString()),
PreTaxVal = Convert.ToDecimal(item_taxable_amount[i].ToString()),
AssAmt = Convert.ToDecimal(item_taxable_amount[i].ToString()) - Convert.ToDecimal(item_discount[i].ToString()),
GstRt = 9,
IgstAmt = Convert.ToDecimal(item_IGST_Amt[i].ToString()),
CgstAmt = Convert.ToDecimal(item_CGST_Amt[i].ToString()),
SgstAmt = Convert.ToDecimal(item_SGST_Amt[i].ToString()),
CesRt = 0,
CesAmt = 0,
OthChrg = 0,
StateCesRt = 0,
StateCesAmt = 0,
StateCesNonAdvlAmt = 0,
TotItemVal = item_totalvalue[i].ToString(),
OrdLineRef = null,
OrgCntry = null,
PrdSlNo = null,
BchDtls = null,
});
}
}
I Want Such Output:
[
{
"Version":"1.1",
"DocDtls": {
"Typ": "Invoice",
"No": "6",
"Dt": "4/1/2022"
},
"ItemList":[{
"SlNo": "9",
"PrdDesc": null,
"IsServc": "Y",
"HsnCd": "22029030",
"Barcde": null,
"Qty": 1.0,
"FreeQty": 0.0,
"Unit": null,
"UnitPrice": 600.84,
"TotAmt": 600.84,
"Discount": 0.00,
"PreTaxVal": 600.84,
"AssAmt": 600.84,
"GstRt": 9,
"IgstAmt": 0.0,
"CgstAmt": 36.05,
"SgstAmt": 36.05,
"CesRt": 0,
"CesAmt": 0,
"OthChrg": 0,
"StateCesRt": 0,
"StateCesAmt": 0,
"StateCesNonAdvlAmt": 0,
"TotItemVal": "672.94",
"OrdLineRef": null,
"PrdSlNo": null,
"OrgCntry": null,
"BchDtls": null,
"Attributedetails": null
},
{
"SlNo": "10",
"PrdDesc": null,
"IsServc": "Y",
"HsnCd": "22029090",
"Barcde": null,
"Qty": 3.0,
"FreeQty": 0.0,
"Unit": null,
"UnitPrice": 1641.38,
"TotAmt": 4924.14,
"Discount": 0.00,
"PreTaxVal": 4924.14,
"AssAmt": 4924.14,
"GstRt": 9,
"IgstAmt": 0.0,
"CgstAmt": 295.45,
"SgstAmt": 295.45,
"CesRt": 0,
"CesAmt": 0,
"OthChrg": 0,
"StateCesRt": 0,
"StateCesAmt": 0,
"StateCesNonAdvlAmt": 0,
"TotItemVal": "5515.04",
"OrdLineRef": null,
"PrdSlNo": null,
"OrgCntry": null,
"BchDtls": null,
"Attributedetails": null
}
]
}
]

In R how to replicate highchart chart with highcharter package

I need to replicate this chart bellow in my shiny app. But I am struggling to deal with the javascript part Any help would be amazing:
Clock Chart Highchart
This is the javascript code: how do I 'translate' this to R?
Any help/indication to deal with javascript in R would be amazing.
Many many tahnks guys
`/**
* Get the current time
*/
function getNow() {
var now = new Date();
return {
hours: now.getHours() + now.getMinutes() / 60,
minutes: now.getMinutes() * 12 / 60 + now.getSeconds() * 12 / 3600,
seconds: now.getSeconds() * 12 / 60
};
}
/**
* Pad numbers
*/
function pad(number, length) {
// Create an array of the remaining length + 1 and join it with 0's
return new Array((length || 2) + 1 - String(number).length).join(0) + number;
}
var now = getNow();
// Create the chart
Highcharts.chart('container', {
chart: {
type: 'gauge',
plotBackgroundColor: null,
plotBackgroundImage: null,
plotBorderWidth: 0,
plotShadow: false,
height: '80%'
},
credits: {
enabled: false
},
title: {
text: 'The Highcharts clock'
},
pane: {
background: [{
// default background
}, {
// reflex for supported browsers
backgroundColor: Highcharts.svg ? {
radialGradient: {
cx: 0.5,
cy: -0.4,
r: 1.9
},
stops: [
[0.5, 'rgba(255, 255, 255, 0.2)'],
[0.5, 'rgba(200, 200, 200, 0.2)']
]
} : null
}]
},
yAxis: {
labels: {
distance: -20
},
min: 0,
max: 12,
lineWidth: 0,
showFirstLabel: false,
minorTickInterval: 'auto',
minorTickWidth: 1,
minorTickLength: 5,
minorTickPosition: 'inside',
minorGridLineWidth: 0,
minorTickColor: '#666',
tickInterval: 1,
tickWidth: 2,
tickPosition: 'inside',
tickLength: 10,
tickColor: '#666',
title: {
text: 'Powered by<br/>Highcharts',
style: {
color: '#BBB',
fontWeight: 'normal',
fontSize: '8px',
lineHeight: '10px'
},
y: 10
}
},
tooltip: {
formatter: function () {
return this.series.chart.tooltipText;
}
},
series: [{
data: [{
id: 'hour',
y: now.hours,
dial: {
radius: '60%',
baseWidth: 4,
baseLength: '95%',
rearLength: 0
}
}, {
id: 'minute',
y: now.minutes,
dial: {
baseLength: '95%',
rearLength: 0
}
}, {
id: 'second',
y: now.seconds,
dial: {
radius: '100%',
baseWidth: 1,
rearLength: '20%'
}
}],
animation: false,
dataLabels: {
enabled: false
}
}]
},
// Move
function (chart) {
setInterval(function () {
now = getNow();
if (chart.axes) { // not destroyed
var hour = chart.get('hour'),
minute = chart.get('minute'),
second = chart.get('second'),
// run animation unless we're wrapping around from 59 to 0
animation = now.seconds === 0 ?
false : {
easing: 'easeOutBounce'
};
// Cache the tooltip text
chart.tooltipText =
pad(Math.floor(now.hours), 2) + ':' +
pad(Math.floor(now.minutes * 5), 2) + ':' +
pad(now.seconds * 5, 2);
hour.update(now.hours, true, animation);
minute.update(now.minutes, true, animation);
second.update(now.seconds, true, animation);
}
}, 1000);
});
/**
* Easing function from https://github.com/danro/easing-js/blob/master/easing.js
*/
Math.easeOutBounce = function (pos) {
if ((pos) < (1 / 2.75)) {
return (7.5625 * pos * pos);
}
if (pos < (2 / 2.75)) {
return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
}
if (pos < (2.5 / 2.75)) {
return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
}
return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
};`
This converts that JS into R/JS (you need to collect time in Javascript). I noticed odd vertical lines in the Viewer pane of RStudio when this runs, but these lines don't appear in my browser.
For most calls in JS for highcharter, the function or argument is identical in R. I used lubridate for the time functions in the R code. (Although, you could set the time to static values because the time isn't controlled by R code.)
After creating the graph, I used htmlwidgets::onRender to give add the animation so that it follows actual time.
If you run this without htmlwidgets, this is what you'll see. (Well, you'll see the time on the clock for your local time at the moment you render it.)
library(highcharter)
library(lubridate)
highchart() %>%
hc_chart(type = "gauge", plotBackgroundColor = NULL,
plotBackgroundImage = NULL, plotBorderWidth = 0,
plotShadow = F) %>%
hc_pane(
background = list(
backgroundColor = list(
radialGradient = list(cx = .5, cy = -.4, r = 1.9),
stops = list(
list(.5, "rgba(255, 255, 255, .2)"),
list(.5, "rgba(200, 200, 200, .2)"))
))) %>%
hc_tooltip(enabled = FALSE) %>%
hc_yAxis(
labels = list(distance = -20),
min = 0, max = 12, lineWidth = 0, showFirstLabel = F,
minorTickInterval = "auto", minorTickWidth = 1,
minorTickColor = "#666", tickColor = "#666",
minorTickPosition = "inside", minorGridLineWidth = 0,
tickInterval = 1, tickWidth = 2, tickPosition = "inside",
tickLength = 10) %>%
hc_add_series(
data = list(
list(id = "hour", y = hour(now()), dial = list(
radius = "60%", baseWidth = 4, baseLength = "95%", rearLength = 0)),
list(id = "minute", y = minute(now()), dial = list(
baseLength = "95%", rearLength = 0)),
list(id = "second", y = second(now()), dial = list(
radius = "100%", baseWidth = 1, rearLength = "20%"))),
dataLabels = list(enabled = F)) %>%
htmlwidgets::onRender("
function(el, x) {
chart = $('#' + el.id).highcharts()
$.extend($.easing, {
easeOutElastic: function (x, t, b, c, d) {
var s = 1.70158; var p = 0; var a = c;
if (t == 0) return b; if ((t /= d) == 1) return b+c;
if (!p) p = d*.3;
if (a < Math.abs(c)) { a = c; var s = p/4; }
else var s = p/(2 * Math.PI) * Math.asin (c/a);
return a * Math.pow(2, -10 * t) * Math.sin( (t * d - s) * (2 * Math.PI)/p) + c + b;
}
});
function getNow () {
var now = new Date();
return {
hours: now.getHours() + now.getMinutes() / 60,
minutes: now.getMinutes() * 12 / 60 + now.getSeconds() * 12 / 3600,
seconds: now.getSeconds() * 12 / 60
};
};
setInterval(function () {
var hour = chart.get('hour'),
minute = chart.get('minute'),
second = chart.get('second'),
now = getNow(),
/* run animation unless we're wrapping around from 59 to 0 */
animation = now.seconds == 0 ?
false : {easing: 'easeOutElastic'};
hour.update(now.hours, true, animation);
minute.update(now.minutes, true, animation);
second.update(now.seconds, true, animation);
}, 1000);
}")
In this JS, you'll see some deviation from the original code. I needed to define 'chart'. I did that using the same mechanism that is used to change any highcharter R object into it's HTML rendering: chart = $('#' + el.id).highcharts(). Since the function that sets the interval was originally part of creating the graph, it was an unnamed function. Since we're calling after we render the graph, I dropped that outer function(chart).

Is there a better way of writing this data structure in Dart?

Map in Dart is an hash table, am I right?
Map starsData = {
'stars':{
'star1': {'x': 0, 'y': 10},
'star2': {'x': 0, 'y': 10}
}
};
This object below in JavaScript can be accessed as an hash table, faster!! I just want to do the some in Dart, but I am not sure if the best way is using Map.
const starsData = {
stars:{
'star1': {'x': 0, 'y': 10},
'star2': {'x': 0, 'y': 10}
}
};
I have rewritten your JavaScript implementation (based on the project your linked: https://github.com/ToniCalfim/fallingstars/blob/master/index.js) in Dart:
Can also be tested with:
https://dartpad.dev/900989f4e35e5a61200e4ad04ecd399a
import 'dart:html';
import 'dart:math' as math;
const starsDiameter = 1.25;
const colorPallete = [
'white',
'yellow',
'blue',
'red',
'orange',
'turquoise',
'purple',
'green',
'lightblue',
'lightyellow',
'lightgreen',
'darkred',
'darkblue',
'darkorange',
'darkturquoise',
'darkgreen'
];
final math.Random _rnd = math.Random();
int getRandomNumber(int min, int max) => min + _rnd.nextInt(max - min);
class Star {
int x, y;
int positionX = getRandomNumber(2, 650);
int positionY = getRandomNumber(3, 125);
double diameter = starsDiameter;
int pulsing = 0;
int blinking = 0;
int timeToFall = getRandomNumber(0, 7500);
int velocityToFall = getRandomNumber(1, 5);
int directionToFall = getRandomNumber(-1, 1);
String color = colorPallete[getRandomNumber(0, colorPallete.length)];
Star() {
x = positionX;
y = positionY;
}
}
final List<Star> stars = List.generate(175, (_) => Star());
void update() {
for (final currentStar in stars) {
final currentTimeToFall = currentStar.timeToFall;
if (currentTimeToFall != 0) {
currentStar.timeToFall = currentTimeToFall - 1;
} else {
final currentVelocityToFall = currentStar.velocityToFall;
final currentAngleToFall = currentStar.directionToFall;
final currentPositionX = currentStar.x;
final currentPositionY = currentStar.y;
currentStar.x = currentPositionX + 1 * currentAngleToFall;
currentStar.y = currentPositionY + currentVelocityToFall;
}
}
}
final CanvasElement canvas = querySelector('#canvas') as CanvasElement;
final CanvasRenderingContext2D context2D = canvas.context2D;
void drawStars() {
context2D.clearRect(
0, 0, context2D.canvas.width, context2D.canvas.height); // Clear canvas
for (final currentStar in stars) {
context2D.beginPath();
context2D.fillStyle = currentStar.color;
context2D.arc(currentStar.x, currentStar.y, starsDiameter, 0, 2 * math.pi);
context2D.fill();
context2D.closePath();
}
}
void animateLoop([num highResTime]) {
update();
drawStars();
window.requestAnimationFrame(animateLoop);
}
void main() {
animateLoop();
}
By looking at your code I could not see any reason why the stars should be saved in a Map or other Hash tables related structure. You are using the stars in two ways: draw and update. In both cases your are just going through all the stars which can be done by using a simple list and iterate over all elements.
I should add that I am not a front-end programmer and I cannot really judge if the way your are drawing the 2D canvas is the most efficient way to do that. My converted code are only are attempt to show how the data could be structured in Dart.

FiddlerCore: how to handle TCP traffic?

I want to use fiddlercore as a reverse proxy - to parse HTTP requests and redirect them to another ports depending on HTTP headers. But I need also handle TCP requests and redirect them to some another port. Is it possible using FiddlerCore? Somehow identify that it is not an HTTP request, just TCP.
I've found event named BeforeReturningError but it's not called.
Only event BeforeSocketAccept is triggered but it's not enough. I haven't found any other events that might be called when FiddlerCore failed to parse HTTP headers.
Fiddler and FiddlerCore only handle HTTP/HTTPS traffic. They are not designed to handle raw TCP traffic; you could use something like netcat for that.
To can TCP packets you can use Pcap library. As such fiddlercore don't work with TCP or UDP packets.
private void PacketHandler(Packet packet)
{
this.count = ""; this.time = ""; this.source = ""; this.destination = ""; this.protocol = ""; this.length = "";
this.tcpack = ""; this.tcpsec = ""; this.tcpnsec = ""; this.tcpsrc = ""; this.tcpdes = ""; this.udpscr = "";
this.udpdes = ""; this.httpheader = ""; this.httpver = ""; this.httplen = ""; this.reqres = ""; this.httpbody = "";
IpV4Datagram ip = packet.Ethernet.IpV4;
TcpDatagram tcp = ip.Tcp;
UdpDatagram udp = ip.Udp;
HttpDatagram httpPacket=null;
if (ip.Protocol.ToString().Equals("Tcp"))
{
httpPacket = tcp.Http;//Initialize http variable only if the packet was tcp
if ((httpPacket.Header != null) && (!_tcp.Checked))
{
protocol = "Http";
httpheader = httpPacket.Header.ToString();
count = packet.Count.ToString();
time = packet.Timestamp.ToString();
this.source = ip.Source.ToString();
this.destination = ip.Destination.ToString();
length = ip.Length.ToString();
httpver = httpPacket.Version.ToString();
httplen = httpPacket.Length.ToString();
httpbody = httpPacket.Body.ToString();
if (httpPacket.IsRequest)
{
reqres = "Request";
}
else
{
reqres = "Response";
}
}
else
{
count = packet.Count.ToString();
time = packet.Timestamp.ToString();
this.source = ip.Source.ToString();
this.destination = ip.Destination.ToString();
length = ip.Length.ToString();
protocol = ip.Protocol.ToString();
tcpsrc = tcp.SourcePort.ToString();
tcpdes = tcp.DestinationPort.ToString();
tcpack = tcp.AcknowledgmentNumber.ToString();
tcpsec = tcp.SequenceNumber.ToString();
tcpnsec = tcp.NextSequenceNumber.ToString();
}
}
else
{
if ((ip.Protocol.ToString().Equals("Udp")))
{
count = packet.Count.ToString();
time = packet.Timestamp.ToString();
this.source = ip.Source.ToString();
this.destination = ip.Destination.ToString();
length = ip.Length.ToString();
protocol = ip.Protocol.ToString();
udpscr = udp.SourcePort.ToString();
udpdes = udp.DestinationPort.ToString();
}
else
{
count = packet.Count.ToString();
time = packet.Timestamp.ToString();
this.source = ip.Source.ToString();
this.destination = ip.Destination.ToString();
length = ip.Length.ToString();
protocol = ip.Protocol.ToString();
}
}
if (ip.Protocol.ToString().Equals("Tcp")&&(save.Checked))
{
int _source = tcp.SourcePort;
int _destination = tcp.DestinationPort;
if (tcp.PayloadLength != 0) //not syn or ack
{
payload = new byte[tcp.PayloadLength];
tcp.Payload.ToMemoryStream().Read(payload, 0, tcp.PayloadLength);// read payload from 0 to length
if (_destination == 80)// request from server
{
Packet1 packet1 = new Packet1();
int i = Array.IndexOf(payload, (byte)32, 6);
byte[] t = new byte[i - 5];
Array.Copy(payload, 5, t, 0, i - 5);
packet1.Name = System.Text.ASCIIEncoding.ASCII.GetString(t);
if (!packets.ContainsKey(_source))
packets.Add(_source, packet1);
}
else
if (_source == 80)
if (packets.ContainsKey(_destination))
{
Packet1 packet1 = packets[_destination];
if (packet1.Data == null)
{
if ((httpPacket.Header != null) && (httpPacket.Header.ContentLength != null))
{
packet1.Data = new byte[(uint)httpPacket.Header.ContentLength.ContentLength];
Array.Copy(httpPacket.Body.ToMemoryStream().ToArray(), packet1.Data, httpPacket.Body.Length);
packet1.Order = (uint)(tcp.SequenceNumber + payload.Length - httpPacket.Body.Length);
packet1.Data_Length = httpPacket.Body.Length;
for (int i = 0; i < packet1.TempPackets.Count; i++)
{
Temp tempPacket = packet1.TempPackets[i];
Array.Copy(tempPacket.data, 0, packet1.Data, tempPacket.tempSeqNo - packet1.Order, tempPacket.data.Length);
packet1.Data_Length += tempPacket.data.Length;
}
}
else
{
Temp tempPacket = new Temp();
tempPacket.tempSeqNo = (uint)tcp.SequenceNumber;
tempPacket.data = new byte[payload.Length];
Array.Copy(payload, tempPacket.data, payload.Length);
packet1.TempPackets.Add(tempPacket);
}
}
else if (packet1.Data_Length != packet1.Data.Length)
{
Array.Copy(payload, 0, packet1.Data, tcp.SequenceNumber - packet1.Order, payload.Length);
packet1.Data_Length += payload.Length;
}
if (packet1.Data != null)
if (packet1.Data_Length == packet1.Data.Length)
{
using (BinaryWriter writer = new BinaryWriter(File.Open(#"D:\captured\" + Directory.CreateDirectory(Path.GetFileName(packet1.Name)), FileMode.Create)))
{
writer.Write(packet1.Data);
}
packets.Remove(_destination);
}
}
}
}
}
This code will help you

OpenCL imaging - only one pixel is updated

I'm using Opencl.net and I'm trying to do some image processing on the GPU. Unfortunately only the first pixel ([0;0]) has the correct value, and the rest is (0;0;0;0). The OpenCL kernel should assign 0.5 to all color components of every pixel. It seems to me that the kernel is being executed only once (or perhaps the read function is reading only the first pixel). What am I doing wrong? I've omitted not relevant parts from my code:
...
int intPtrSize = 0;
intPtrSize = Marshal.SizeOf(typeof(IntPtr));
Cl.Mem srcImage2DBuffer;
Cl.ImageFormat imageFormat = new Cl.ImageFormat(Cl.ChannelOrder.ARGB, Cl.ChannelType.Float);
int imgWidth = 0, imgHeight = 0;
IntPtr srcFloatDataPtr;
int srcIMGBytesSize = 0;
GCHandle pinnedSrcFloatArray;
//Load image from file into OpenCL buffer
using (FileStream imageFileStream = new FileStream(inputImagePath, FileMode.Open) ) {
System.Drawing.Image inputImage = System.Drawing.Image.FromStream( imageFileStream );
imgWidth = inputImage.Width;
imgHeight = inputImage.Height;
System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(inputImage);
BitmapData bitmapData = bmpImage.LockBits( new Rectangle(0, 0, bmpImage.Width, bmpImage.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
srcIMGBytesSize = bitmapData.Stride * bitmapData.Height;
//Convert image from byte to float array
byte[] inputByteArray = new byte[srcIMGBytesSize];
Marshal.Copy(bitmapData.Scan0, inputByteArray, 0, srcIMGBytesSize);
bmpImage.UnlockBits( bitmapData );
float[] inputFloatArray = new float[srcIMGBytesSize];
Array.Copy(inputByteArray, inputFloatArray, srcIMGBytesSize);
for (int i = 0; i < srcIMGBytesSize; i++) {
inputFloatArray[i] /= 255.0f;
}
pinnedSrcFloatArray = GCHandle.Alloc(inputFloatArray, GCHandleType.Pinned);
srcFloatDataPtr = pinnedSrcFloatArray.AddrOfPinnedObject();
srcImage2DBuffer = Cl.CreateImage2D(_context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly, imageFormat,
(IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height,
(IntPtr)0, srcFloatDataPtr, out error);
}
float[] outputFloatArray = new float[srcIMGBytesSize];
//I'm not sure whether the pointer here is correct or not.
Cl.Mem resultImage2DBuffer = Cl.CreateImage2D(_context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.WriteOnly, imageFormat,
(IntPtr)imgWidth, (IntPtr)imgHeight, (IntPtr)0, outputFloatDataPtr, out error);
error = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, srcImage2DBuffer);
error |= Cl.SetKernelArg(kernel, 1, (IntPtr)intPtrSize, resultImage2DBuffer);
...
IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 };
IntPtr[] regionPtr = new IntPtr[] { (IntPtr)1, (IntPtr)1, (IntPtr)1 };
IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)imgWidth, (IntPtr)imgHeight, (IntPtr)1 };
error = Cl.EnqueueWriteImage(cmdQueue, srcImage2DBuffer, Cl.Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, srcFloatDataPtr, 0, null, out clevent);
pinnedSrcFloatArray.Free();
error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent);
error = Cl.EnqueueReadImage(cmdQueue, resultImage2DBuffer, Cl.Bool.True, originPtr, regionPtr,
(IntPtr)0, (IntPtr)0, outputFloatArray, 0, null, out clevent);
for (int i = 0; i < srcIMGBytesSize; i++) {
outputFloatArray[i] *= 255.0f;
}
//Right here I'm learning that all of the components are 0
for (int i = 0; i < srcIMGBytesSize; i+=4) {
Console.WriteLine("(" + outputFloatArray[i] + "; " + outputFloatArray[i+1] + "; "
+ outputFloatArray[i+2] + "; " + outputFloatArray[i+3] + ")");
}
Thank you!
I've figured out the problem. The region in Cl.EnqueueWriteImage/Cl.EnqueueReadImage should be (imageWidth, imageHeight, 1) instead of (1, 1, 1):
IntPtr[] regionPtr = new IntPtr[] { (IntPtr)imgWidth, (IntPtr)imgHeight, (IntPtr)1 };

Resources