I am not able to figure out anyway on how to disbale 3 way hanshake in ns3
I am using NetAnim to trace the packets of the Below code
#include <fstream>
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/sixlowpan-module.h"
#include "ns3/lr-wpan-module.h"
#include "ns3/internet-apps-module.h"
#include "ns3/mobility-module.h"
#include "ns3/netanim-module.h"
using namespace ns3;
using namespace std;
NS_LOG_COMPONENT_DEFINE ("Ping6WsnExample");
int
main (int argc, char **argv)
{
bool verbose = false;
CommandLine cmd (__FILE__);
cmd.AddValue ("verbose", "turn on log components", verbose);
cmd.Parse (argc, argv);
cout << "verbose : " << verbose << endl;
LogComponentEnable ("Ping6WsnExample", LOG_LEVEL_INFO);
NS_LOG_INFO ("Create nodes.");
NodeContainer nodes;
int n = 3;
nodes.Create (n);
SeedManager::SetSeed (167);
// Install mobility
MobilityHelper mobility;
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
Ptr<ListPositionAllocator> nodesPositionAlloc = CreateObject<ListPositionAllocator> ();
for (int i = 0; i < n; i++)
nodesPositionAlloc->Add (Vector (0.0 + i * 5, 0.0, 0.0));
mobility.SetPositionAllocator (nodesPositionAlloc);
mobility.Install (nodes);
NS_LOG_INFO ("Create channels.");
LrWpanHelper lrWpanHelper;
// Add and install the LrWpanNetDevice for each node
// lrWpanHelper.EnableLogComponents();
NetDeviceContainer devContainer = lrWpanHelper.Install (nodes);
lrWpanHelper.AssociateToPan (devContainer, 10);
cout << "Created " << devContainer.GetN () << " devices" << endl;
cout << "There are " << nodes.GetN () << " nodes" << endl;
/* Install IPv4/IPv6 stack */
NS_LOG_INFO ("Install Internet stack.");
InternetStackHelper internetv6;
internetv6.SetIpv4StackInstall (false);
internetv6.Install (nodes);
// Install 6LowPan layer
NS_LOG_INFO ("Install 6LoWPAN.");
SixLowPanHelper sixlowpan;
NetDeviceContainer six1 = sixlowpan.Install (devContainer);
NS_LOG_INFO ("Assign addresses.");
Ipv6AddressHelper ipv6;
ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
Ipv6InterfaceContainer i = ipv6.Assign (six1);
NS_LOG_INFO ("Run Simulation.");
AnimationInterface anim ("animation.xml");
Simulator::Run ();
Simulator::Destroy ();
NS_LOG_INFO ("Done.");
}
I don't want the packets of 3 way handshake to be visualised in NetAnim (to differentiate other packets and handshaking packets)
So what should I do to differentiate them ?
Note : I am new to ns3 so tips on using NS3 is more appreciable
Related
Now I want to do something on the branch and bound using SCIP, and begin from the branching rule. While I tracking the branching process I found something I cannot understand. Begining from getting the branching variable candidates using SCIPgetLPBranchCands, I get the SCIP_VAR** lpcands, then I select the first variable to branch using SCIPbranchVar. This branching rule works on each focused node.
Consider the branch decision at the number 1 node (the root node), after executing SCIPbranchVar function, SCIPgetChildren return two child nodes (2 and 3), but the child node number of root node changed, two or more child node appeared. Suppose node selector selected the node of number 2 to branch, SCIPgetSiblings return 3 siblings (3, 4, and 5).
To make it clear that what happened, I print the branching decision path using SCIPprintNodeRootPath, and print the relationship between nodes. The result shows that after I branching at a node on the selected variable, the SCIIP branching at the same node on another variable which I don't know.
I have print these information generated by scipoptsuite-7.0.1/scip/examples/Binpacking, no more branching decision is made. But more child nodes appearing after I replace the ryanfoster rule using the branching on the first variable. After that, I try the create child node branching style for my procedure, extra nodes appeared anyway.
I cannot find out what happened and how to totally control the branching process, it is very important for my work in the future for it determined how to design the branching rule. I have even try to read the source code of SCIP, unfortunately, it's too hard for me to read.
My procedure as follows:
main.cpp
/* standard library includes */
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
/* scip includes */
#include "objscip/objscip.h"
#include "objscip/objscipdefplugins.h"
/*user file includes*/
#include "branch_rule.h"
/* namespace usage */
using namespace std;
using namespace scip;
static
SCIP_RETCODE execmain()
{
SCIP* scip = NULL;
/* initialize SCIP environment */
SCIP_CALL( SCIPcreate(&scip) );
SCIP_CALL( SCIPincludeBranchRrule(scip) );
/* include default plugins */
SCIP_CALL( SCIPincludeDefaultPlugins(scip) );
SCIP_CALL( SCIPsetIntParam(scip,"presolving/maxrestarts",0) );
SCIP_CALL( SCIPsetSeparating(scip, SCIP_PARAMSETTING_OFF, TRUE) );
SCIP_CALL(SCIPreadProb(scip, "map18.mps.gz", NULL));
SCIP_CALL( SCIPsolve(scip) );
return SCIP_OKAY;
}
int main(int argc, char** argv)
{
return execmain() != SCIP_OKAY ? 1 : 0;
}
branch_rule.h
#ifndef VRP_BRANCH_RULE_H
#define VRP_BRANCH_RULE_H
#include "scip/scip.h"
#include <vector>
SCIP_RETCODE SCIPincludeBranchRrule(
SCIP* scip
);
#endif //VRP_BRANCH_RULE_H
branch_rule.cpp
#include "branch_rule.h"
#include <assert.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>
#include "scip/struct_tree.h"
#include "scip/type_var.h"
using namespace std;
/**#name Branching rule properties
*
* #{
*/
#define BRANCHRULE_NAME "branch rule test"
#define BRANCHRULE_DESC "branch rule test"
#define BRANCHRULE_PRIORITY 50000
#define BRANCHRULE_MAXDEPTH -1
#define BRANCHRULE_MAXBOUNDDIST 1.0
void printBranchTreeNode(SCIP_NODE *node, SCIP_NODE **siblings, int nsiblings){
ofstream f1("branch_path/node_information.txt", ios::app);
if(!f1)return;
f1 << "node number:" << node->number << ", sibling number: " << nsiblings;
if(NULL==node->parent)
f1 << std::endl;
else{
f1 << ", parent number: " << node->parent->number << std::endl;
}
f1 << setw(20) << "siblings:" << std::endl;
for(int i = 0; i < nsiblings; ++i){
f1 << setw(20) << "node number:" << siblings[i]->number << ", sibling number: " << nsiblings << ", parent number: " << siblings[i]->parent->number << endl;
}
f1.close();
}
static
SCIP_DECL_BRANCHEXECLP(branchExeclpTest)
{
assert(scip != NULL);
assert(branchrule != NULL);
assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
assert(result != NULL);
SCIP_NODE *current_node = SCIPgetCurrentNode(scip) ;
SCIP_NODE **leaves = NULL;
int nleaves;
SCIP_CALL( SCIPgetLeaves (scip, &leaves, &nleaves) );
std::vector<SCIP_NODE*> leaves_vector;
for(int i =0; i < nleaves; ++i){
leaves_vector.push_back(leaves[i]);
}
SCIP_NODE **current_node_slibings = NULL;
int ncurrent_node_slibings;
SCIP_CALL( SCIPgetSiblings(scip, ¤t_node_slibings, &ncurrent_node_slibings) );
std::vector<SCIP_NODE*> slibings_vector;
for(int i =0; i < ncurrent_node_slibings; ++i){
slibings_vector.push_back(current_node_slibings[i]);
}
printBranchTreeNode(current_node, current_node_slibings, ncurrent_node_slibings);
SCIP_NODE **childrens;
int nchildrens;
SCIP_CALL( SCIPgetChildren(scip, &childrens, &nchildrens) );
std::vector<SCIP_NODE*> childrens_vector;
for(int i =0; i < nchildrens; ++i){
childrens_vector.push_back(childrens[i]);
}
stringstream filename;
filename.str("");
filename << "branch_path/branch_path_to_node_" << current_node->number <<".dat";
std::string stringFileName = filename.str();
FILE *fp = fopen(stringFileName.c_str(), "wt+");
SCIP_CALL( SCIPprintNodeRootPath(scip, current_node, fp) );
fclose(fp);
// create child node branching style
SCIP_NODE *childsame;
SCIP_NODE *childdiffer;
SCIP_CALL( SCIPcreateChild(scip, &childsame, 0.0, SCIPgetLocalTransEstimate(scip)) );
SCIP_CALL( SCIPcreateChild(scip, &childdiffer, 0.0, SCIPgetLocalTransEstimate(scip)) );
/*
// SCIPbranchVar branching style
SCIP_VAR** lpcands;
SCIP_Real* lpcandssol;
SCIP_Real* lpcandsfrac;
int nlpcands;
int npriolpcands;
int nfracimplvars;
SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, &lpcandsfrac, &nlpcands, &npriolpcands, &nfracimplvars) );
SCIP_NODE* downchild;
SCIP_NODE* eqchild;
SCIP_NODE* upchild;
SCIP_CALL( SCIPbranchVar(scip, lpcands[0], &downchild, &eqchild, &upchild) );
// SCIP_CALL( SCIPbranchVar(scip, var, NULL, NULL, NULL) );
SCIP_CALL( SCIPgetLeaves (scip, &leaves, &nleaves) );
int numLeaves = SCIPgetNLeaves(scip);
SCIP_CALL( SCIPgetSiblings(scip, ¤t_node_slibings, &ncurrent_node_slibings) );
slibings_vector.clear();
for(int i =0; i < ncurrent_node_slibings; ++i){
slibings_vector.push_back(current_node_slibings[i]);
}
SCIP_CALL( SCIPgetChildren(scip, &childrens, &nchildrens) );
childrens_vector.clear();
for(int i =0; i < nchildrens; ++i){
childrens_vector.push_back(childrens[i]);
}
*/
return SCIP_OKAY;
}
SCIP_RETCODE SCIPincludeBranchRrule(
SCIP* scip /**< SCIP data structure */
){
SCIP_BRANCHRULEDATA* branchruledata;
SCIP_BRANCHRULE* branchrule;
branchruledata = NULL;
branchrule = NULL;
// include branching rule
SCIP_CALL( SCIPincludeBranchruleBasic(scip, &branchrule, BRANCHRULE_NAME, BRANCHRULE_DESC, BRANCHRULE_PRIORITY, BRANCHRULE_MAXDEPTH,
BRANCHRULE_MAXBOUNDDIST, branchruledata) );
assert(branchrule != NULL);
SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpTest) );
return SCIP_OKAY;
}
Does anyone can help me to solve this problem?
so the first thing I notice when looking at your code is that you do not set the result pointer. After branching, you need to set *result = SCIP_BRANCHED;.
Can you please try that and check if it fixes your problem?
I am currently trying to use an ATtiny84 to communicate with an RTC (DS1305) through SPI to make an buzzer vibrate every variable amount of time. I've been trying to set alarm0 on the DS1305. However, the 84 does not "technically" have SPI. It has USI which can be programmed to be like SPI. I was wondering if any of you could review my code/ board connections and let me know if you see any problems. The current problem is that I cannot get any communication going through SPI and I am having trouble finding what the issue could be.
Current board connections:
ATtiny84 | DS1305
MOSI ------ DI
MISO ------ DO
USCLK ---- CLK
Datasheets:
Attiny84
DS1305
/*
* Atmel_Jolt_Code.c
*
* Created: 11/28/2018 10:44:30 PM
* Author : Nick Hulsey
*/
#include <avr/io.h>
#define F_CPU 16000000UL
#include <avr/interrupt.h>
#include <util/delay.h>
//variables for SPI
#define SPI_DDR_PORT DDRA
#define CE_PIN DDA3 //I ADDED *****
#define DO_DD_PIN DDA5 // SHOULD WE
#define DI_DD_PIN DDA6 // THEM FLIP
#define USCK_DD_PIN DDA4
#define SPI_MODE0 0x00
#define SPI_MODE1 0x04
#define MOTOR_PIN DDA7 //I ADDED *****
void SPI_begin();
void setDataMode(uint8_t spiDataMode);
uint8_t transfer(uint8_t spiData);
void flipLatch(uint8_t on);
int main(void)
{
SPI_begin();
setDataMode(SPI_MODE1);
DDRA |= (1 << MOTOR_PIN);
//**startup**
uint8_t status_register = 0x10;
uint8_t control_register = 0x8F;
uint8_t control_byte = 0x05;
uint8_t alarm_registers[] = {0x8A, 0x89, 0x88, 0x87};
//set control
flipLatch(1);
transfer(control_register);
transfer(0);
flipLatch(0);
flipLatch(1);
transfer(control_register);
transfer(control_byte);
flipLatch(0);
//set alarm:
for (int i = 0; i < 4; i++){
flipLatch(1);
transfer(alarm_registers[i]);
transfer(0x80); //0b10000000
flipLatch(0);
}
//THIS MIGHT NEED WORK
//GIMSK |= (1 << PCIE1);//set external interrupt (A1)
PCMSK0 |= (1 << PCINT1);
sei();
while (1) //our main loop
{
//reading the flag from the status register
uint8_t status = transfer(status_register);
if(status == 0x01){//if alarm 0 has been flagged
PORTA ^= (1 << MOTOR_PIN);
_delay_ms(100);
}
}
}
//if A1 has changed state at all this function will fire
ISR(PCINT1_vect){
PORTA ^= (1 << MOTOR_PIN);//invert motor power
_delay_ms(100);
}
void SPI_begin(){
USICR &= ~((1 << USISIE) | (1 << USIOIE) | (1 << USIWM0));//Turn off these bits
USICR |= (1 << USIWM0) | (1 << USICS1) | (1 << USICLK);//Turn on these bits
//REVIEW THIS PAGE 128
//external,positive edge software clock
//What does this mean
SPI_DDR_PORT |= 1 << USCK_DD_PIN; // set the USCK pin as output
SPI_DDR_PORT |= 1 << DO_DD_PIN; // set the DO pin as output
SPI_DDR_PORT |= 1 << CE_PIN;// ******** I ADDED
SPI_DDR_PORT &= ~(1 << DI_DD_PIN); // set the DI pin as input
}
void setDataMode(uint8_t spiDataMode)
{
if (spiDataMode == SPI_MODE1)
USICR |= (1 << USICS0);
else
USICR &= (1 << USICS0);
}
//returns values returned from the IC
uint8_t transfer(uint8_t spiData)
{
USIDR = spiData;
USISR = (1 << USIOIF); // clear counter and counter overflow interrupt flag
//ATOMIC_BLOCK(ATOMIC_RESTORESTATE) // ensure a consistent clock period
//{
while ( !(USISR & (1 << USIOIF)) ) USICR |= (1 << USITC);
//}
return USIDR;
}
void flipLatch(uint8_t on){
if (on == 1)
PORTA |= (1 << CE_PIN);
else
PORTA &= ~(1 << CE_PIN);
}
I am new to CGAL.
I tried to modify Examples/Arrangement_on_surfaces_2 Bezier_curves.cpp to save arrangement to file as shown below:
//! \file examples/Arrangement_on_surface_2/Bezier_curves.cpp
// Constructing an arrangement of Bezier curves.
#include <fstream>
#include <CGAL/basic.h>
#ifndef CGAL_USE_CORE
#include <iostream>
int main ()
{
std::cout << "Sorry, this example needs CORE ..." << std::endl;
return 0;
}
#else
#include <CGAL/Cartesian.h>
#include <CGAL/CORE_algebraic_number_traits.h>
#include <CGAL/Arr_Bezier_curve_traits_2.h>
#include <CGAL/Arrangement_2.h>
#include <CGAL/IO/Arr_iostream.h>
#include "arr_inexact_construction_segments.h"
#include "arr_print.h"
typedef CGAL::CORE_algebraic_number_traits Nt_traits;
typedef Nt_traits::Rational NT;
typedef Nt_traits::Rational Rational;
typedef Nt_traits::Algebraic Algebraic;
typedef CGAL::Cartesian<Rational> Rat_kernel;
typedef CGAL::Cartesian<Algebraic> Alg_kernel;
typedef Rat_kernel::Point_2 Rat_point_2;
typedef CGAL::Arr_Bezier_curve_traits_2<Rat_kernel, Alg_kernel, Nt_traits>
Traits_2;
typedef Traits_2::Curve_2 Bezier_curve_2;
typedef CGAL::Arrangement_2<Traits_2> Arrangement_2;
//typedef CGAL::Arrangement_2<Traits_2> Arrangement;
int main (int argc, char *argv[])
{
// Get the name of the input file from the command line, or use the default
// Bezier.dat file if no command-line parameters are given.
const char *filename = (argc > 1) ? argv[1] : "Bezier.dat";
const char *outfilename = (argc > 1) ? argv[1] : "BezierOut.dat";
// Open the input file.
std::ifstream in_file (filename);
if (! in_file.is_open()) {
std::cerr << "Failed to open " << filename << std::endl;
return 1;
}
// Read the curves from the input file.
unsigned int n_curves;
std::list<Bezier_curve_2> curves;
Bezier_curve_2 B;
unsigned int k;
in_file >> n_curves;
for (k = 0; k < n_curves; k++) {
// Read the current curve (specified by its control points).
in_file >> B;
curves.push_back (B);
std::cout << "B = {" << B << "}" << std::endl;
}
in_file.close();
// Construct the arrangement.
Arrangement_2 arr;
insert (arr, curves.begin(), curves.end());
// Print the arrangement size.
std::ofstream out_file;
out_file.open(outfilename);
out_file << "The arrangement size:" << std::endl
<< " V = " << arr.number_of_vertices()
<< ", E = " << arr.number_of_edges()
<< ", F = " << arr.number_of_faces() << std::endl;
out_file << arr;
out_file.close();
return 0;
}
#endif
If I comment out the line out_file << arr; it works fine. Otherwise it generates a C2678 error in read_x_monotone_curve in Arr_text_formtter.h
I am using Visual Studio 15 x86.
Thank you for any help.
I solve this by modifying the print_arrangement(arr) routine in arr_print.h to save_arrangement(arr) with a std::ofstream in place of std::cout.
It appears that the << operator does not work.
If someone else has a better solution I am open to it.
Points of intersections in an arrangement of Bezier curves cannot be represented in an exact manner. Therefore, such an arrangement cannot be saved using the default export (<<) operator and the standard format.
The easiest solution is to store the curves, but this means that the arrangement must be recomputed each time the curves are read. Perhaps other solution could be devised, but they are not implemented.
I have a short test program to fetch the IP address of the local machine. On Raspbian, only the loopback address is returned, while the same code on OS X return both normal and loopback IPs.
The code is
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <errno.h>
using namespace std;
int main (int argc, char * const argv[]) {
char hostname[128];
int result = gethostname(hostname, 127);
if (result != 0) {
cout << "FATAL: gethostname failed: " << result << errno;
return -1;
}
cout << "Host name is " << hostname << endl;
struct addrinfo hints, *res;
int errcode;
char addrstr[100];
void *ptr;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_CANONNAME;
errcode = getaddrinfo(hostname, NULL, &hints, &res);
if (errcode != 0) {
perror("getaddrinfo");
return -1;
}
while(res) {
inet_ntop(res->ai_family, res->ai_addr->sa_data, addrstr, 100);
switch(res->ai_family) {
case AF_INET:
ptr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
break;
case AF_INET6:
ptr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
break;
default:
cout << "Unknown family" << endl;
}
inet_ntop(res->ai_family, ptr, addrstr, 100);
printf("IPV%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4, addrstr, res->ai_canonname);
res = res->ai_next;
}
return 0;
}
On OS X I get:
[Coyote]collector$ ./quick
Host name is Coyote.local
IPV4 address: 192.168.1.108 (coyote.local)
IPV6 address: fe80::223:dfff:fea0:a230 (coyote.local)
But on Raspbian I only get:
pi:~$ ./quick
Host name is pi
IPV4 address: 127.0.1.1 (pi)
yet
pi:~$ ifconfig
eth0 Link encap:Ethernet HWaddr b8:27:eb:62:15:fc
inet addr:192.168.1.162 Bcast:192.168.1.255 Mask:255.255.255.0
[...]
What do I need to do on Raspbian to get the correct result?
This is probably due to the contents of your /etc/hosts file. If your goal is to obtain the ip addresses of the system, consider using getifaddrs instead. It's of BSD origin, but works on Linux as well.
If you want for sure to know which address will be used when you connect somewhere, the best way to do it than to connect and then obtain the address using getsockname. The other option would be to read the routing tables.
Also, getnameinfo is usually a better choice than inet_ntop.
So, after spending hours reading and understanding I have finally made my first OpenCL program that actually does something, which is it adds two vectors and outputs to a file.
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <fstream>
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
int main(int argc, char *argv[])
{
try
{
// get platforms, devices and display their info.
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
std::vector<cl::Platform>::iterator i=platforms.begin();
std::cout<<"OpenCL \tPlatform : "<<i->getInfo<CL_PLATFORM_NAME>()<<std::endl;
std::cout<<"\tVendor: "<<i->getInfo<CL_PLATFORM_VENDOR>()<<std::endl;
std::cout<<"\tVersion : "<<i->getInfo<CL_PLATFORM_VERSION>()<<std::endl;
std::cout<<"\tExtensions : "<<i->getInfo<CL_PLATFORM_EXTENSIONS>()<<std::endl;
// get devices
std::vector<cl::Device> devices;
i->getDevices(CL_DEVICE_TYPE_ALL,&devices);
int o=99;
std::cout<<"\n\n";
// iterate over available devices
for(std::vector<cl::Device>::iterator j=devices.begin(); j!=devices.end(); j++)
{
std::cout<<"\tOpenCL\tDevice : " << j->getInfo<CL_DEVICE_NAME>()<<std::endl;
std::cout<<"\t\t Type : " << j->getInfo<CL_DEVICE_TYPE>()<<std::endl;
std::cout<<"\t\t Vendor : " << j->getInfo<CL_DEVICE_VENDOR>()<<std::endl;
std::cout<<"\t\t Driver : " << j->getInfo<CL_DRIVER_VERSION>()<<std::endl;
std::cout<<"\t\t Global Mem : " << j->getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>()/(1024*1024)<<" MBytes"<<std::endl;
std::cout<<"\t\t Local Mem : " << j->getInfo<CL_DEVICE_LOCAL_MEM_SIZE>()/1024<<" KBbytes"<<std::endl;
std::cout<<"\t\t Compute Unit : " << j->getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>()<<std::endl;
std::cout<<"\t\t Clock Rate : " << j->getInfo<CL_DEVICE_MAX_CLOCK_FREQUENCY>()<<" MHz"<<std::endl;
}
std::cout<<"\n\n\n";
//MAIN CODE BEGINS HERE
//get Kernel
std::ifstream ifs("vector_add_kernel.cl");
std::string kernelSource((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
std::cout<<kernelSource;
//Create context, select device and command queue.
cl::Context context(devices);
cl::Device &device=devices.front();
cl::CommandQueue cmdqueue(context,device);
// Generate Source vector and push the kernel source in it.
cl::Program::Sources sourceCode;
sourceCode.push_back(std::make_pair(kernelSource.c_str(), kernelSource.size()));
//Generate program using sourceCode
cl::Program program=cl::Program(context, sourceCode);
//Build program..
try
{
program.build(devices);
}
catch(cl::Error &err)
{
std::cerr<<"Building failed, "<<err.what()<<"("<<err.err()<<")"
<<"\nRetrieving build log"
<<"\n Build Log Follows \n"
<<program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices.front());
}
//Declare and initialize vectors
std::vector<cl_float>B(993448,1.3);
std::vector<cl_float>C(993448,1.3);
std::vector<cl_float>A(993448,1.3);
cl_int N=A.size();
//Declare and intialize proper work group size and global size. Global size raised to the nearest multiple of workGroupSize.
int workGroupSize=128;
int GlobalSize;
if(N%workGroupSize) GlobalSize=N - N%workGroupSize + workGroupSize;
else GlobalSize=N;
//Declare buffers.
cl::Buffer vecA(context, CL_MEM_READ_WRITE, sizeof(cl_float)*N);
cl::Buffer vecB(context, CL_MEM_READ_ONLY , (B.size())*sizeof(cl_float));
cl::Buffer vecC(context, CL_MEM_READ_ONLY , (C.size())*sizeof(cl_float));
//Write vectors into buffers
cmdqueue.enqueueWriteBuffer(vecB, 0, 0, (B.size())*sizeof(cl_float), &B[0] );
cmdqueue.enqueueWriteBuffer(vecB, 0, 0, (C.size())*sizeof(cl_float), &C[0] );
//Executing kernel
cl::Kernel kernel(program, "vector_add");
cl::KernelFunctor kernel_func=kernel.bind(cmdqueue, cl::NDRange(GlobalSize), cl::NDRange(workGroupSize));
kernel_func(vecA, vecB, vecC, N);
//Reading back values into vector A
cmdqueue.enqueueReadBuffer(vecA,true,0,N*sizeof(cl_float), &A[0]);
cmdqueue.finish();
//Saving into file.
std::ofstream output("vectorAdd.txt");
for(int i=0;i<N;i++) output<<A[i]<<"\n";
}
catch(cl::Error& err)
{
std::cerr << "OpenCL error: " << err.what() << "(" << err.err() <<
")" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
The problem is, for smaller values of N, I'm getting the correct result that is 2.6
But for larger values, like the one in the code above (993448) I get garbage output varying between 1 and 2.4.
Here is the Kernel code :
__kernel void vector_add(__global float *A, __global float *B, __global float *C, int N) {
// Get the index of the current element
int i = get_global_id(0);
//Do the operation
if(i<N) A[i] = C[i] + B[i];
}
UPDATE : Ok it seems the code is working now. I have fixed a few minor mistakes in my code above
1) The part where GlobalSize is initialized has been fixed.
2)Stupid mistake in enqueueWriteBuffer (wrong parameters given)
It is now outputting the correct result for large values of N.
Try to change the data type from float to double etc.