Mkfifo in GNU Octave - octave

I have yet to find a complete example for using the mkfifo() function online. I am able to make the fifo like this:
mkfifo("file",777)
But when I fopen() this file, Octave just hangs. What is the proper way to create, queue, and dequeue bytes from a mkfifo object?
I would like to create an in-memory fifo in Octave (on-disk is fine too) and read and write it from the same Octave script. My project is running in real time, and so I need a buffer so that I can fill and drain from the same Octave script. I've searched for a fifo library with zero results. Even just creating a vector and pushing and popping will suit my needs. I tried this myself, but I'm running into object oriented programming design problems because Octave does not allow pass by reference or pointers.

There are two issues. First: mkfifo expects mode as integer with base 10, if you write "777" you think in octal, base 8. Second: mkfifo uses umask to modify the permissions to (mode & ~umask) (See man 3)
As example:
fn=tempname
[ERR, MSG] = mkfifo (fn, base2dec("744", 8))
stat(fn)
fn = /tmp/oct-83UCBR
ERR = 0
MSG =
ans =
scalar structure containing the fields:
dev = 2053
ino = 3408172
mode = 4580
modestr = prwxr--r--
nlink = 1
uid = 1000
gid = 1000
rdev = 0
size = 0
atime = 1.4311e+09
mtime = 1.4311e+09
ctime = 1.4311e+09
blksize = 4096
blocks = 0
As you can see the modestr is now prwxr--r-- as you would expect from octal 744
Now you can open one end of the FIFO:
fid = fopen (fn, "r")
Of course this blocks until the other end of the fifo gets connected.

The fifo class works, but only up to a certain size. The max size in bytes of a fifo can be found by running:
cat /proc/sys/fs/pipe-max-size
1048576
Below is the code that I wrote for an in-memory fifo. It's fairly crude but it works well:
1; % Prevent Octave from thinking that this is a function file
global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
fifoSamples = zeros(0);
fifoCount = 0;
fifoFiles = cell(1);
fifoFids = zeros(0);
fifoDataType = 'single';
fifoDataTypeSize = 4;
fifoMaxBytes = 1048576; % this is operating system enforced, changing here will not help
function [] = o_fifo_write(index, data)
global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
wrcount = fwrite(fifoFids(index), data, fifoDataType);
[sz,~] = size(data);
fifoSamples(index) = fifoSamples(index) + sz;
if( sz ~= wrcount )
disp(sprintf('o_fifo_write was given %d samples but wrote %d', sz, wrcount));
end
if( ~iscolumn(data) )
disp('data must be columnar in o_fifo_write');
end
end
function [data] = o_fifo_read(index, count)
global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
[data, rdcount] = fread(fifoFids(index), count, fifoDataType);
[sz,~] = size(data);
fifoSamples(index) = fifoSamples(index) - sz;
if( sz ~= rdcount || sz ~= count )
disp(sprintf('in o_fifo_read %d %d %d should all be the same', sz, rdcount, count));
end
end
function [avail] = o_fifo_avail(index)
global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
avail = fifoSamples(index);
end
function index = o_fifo_new()
global fifoCount fifoSamples fifoFiles fifoFids fifoDataType
fifoCount = fifoCount + 1;
index = fifoCount;
fifoSamples(index) = 0;
fifoFiles{index} = tempname;
[ERR, MSG] = mkfifo(fifoFiles{index}, base2dec('744',8));
fifoFids(index) = fopen(fifoFiles{index}, 'a+');
% fcntl(fifoFids(index), F_SETFL, O_NONBLOCK); % uncomment to avoid hangs when trying to overfill fifo
end
% ---- usage -----
txfifo = o_fifo_new();
disp(o_fifo_avail(txfifo));
o_fifo_write(txfifo, [1.243 pi 2*pi 4/3*pi]');
disp(o_fifo_avail(txfifo));
disp(o_fifo_read(txfifo, 4));
disp(o_fifo_avail(txfifo));

Related

Can't save data using push button (MATLAB)

I'm trying to create a figure where the user can select cells to turn on or off. Then, the user can click a button 'Enter' to save the board as an array. I successfully found a way to create interactivity in my plot thanks to a very useful explanation I found here. I just made some changes to suit my needs.
However, I can't find a way to save the board. The button is working (or at least isn't not working), but the data isn't saved. And I don't know how to fix that. Any help would be appreciated.
Here is my code:
function CreatePattern
hFigure = figure;
hAxes = axes;
axis equal;
axis off;
hold on;
% create a button to calculate the difference between 2 points
h = uicontrol('Position',[215 5 150 30],'String','Enter','Callback', #SaveArray);
function SaveArray(ButtonH, eventdata)
global initial
initial = Board;
close(hFigure)
end
N = 1; % for line width
M = 20; % board size
squareEdgeSize = 1;
% create the board of patch objects
hPatchObjects = zeros(M,M);
for j = M:-1:1
for k = 1:M
hPatchObjects(M - j+ 1, k) = rectangle('Position', [k*squareEdgeSize,j*squareEdgeSize,squareEdgeSize,squareEdgeSize], 'FaceColor', [0 0 0],...
'EdgeColor', 'w', 'LineWidth', N, 'HitTest', 'on', 'ButtonDownFcn', {#OnPatchPressedCallback, M - j+ 1, k});
end
end
%global Board
Board = zeros(M,M);
playerColours = [1 1 1; 0 0 0];
xlim([squareEdgeSize M*squareEdgeSize]);
ylim([squareEdgeSize M*squareEdgeSize]);
function OnPatchPressedCallback(hObject, eventdata, rowIndex, colIndex)
% change FaceColor to player colour
value = Board(rowIndex,colIndex);
if value == 1
set(hObject, 'FaceColor', playerColours(2, :));
Board(rowIndex,colIndex) = 0; % update board
else
set(hObject, 'FaceColor', playerColours(1, :));
Board(rowIndex,colIndex) = 1; % update board
end
end
end
%imwrite(~pattern,'custom_pattern.jpeg')

Trouble Calling Terms from Function

I have a code that defines a function, then I try to use the variables I defined within that function in another expression. When I do this, I get an error that is:
Undefined function or variable 'phi'.
I'm not sure why phi is undefined, since I have it in the if/else statement.
It might be better to explain with my (shortened) code:
global I11 I22 I33 Mx My Mz w10 w20 w30 eps10 eps20 eps30 eps40...
C110 C120 C130 C210 C220 C230 C310 C320 C330 IC K0
IC = [w10 w20 w30...
eps10 eps20 eps30 eps40...
C110 C120 C130 C210 C220 C230 C310 C320 C330];
opts = odeset('RelTol', 1*10^(-10),'AbsTol', 1*10^(-10));
[t, y] = ode45(#(t,y) DynEqn2(t,y,I11,I22,I33,Mx,My,Mz), [ti tf], IC, opts);
N = sqrt(sum(y(:,4:7).^2,2));
kap = acosd(1-2*y(:,5).^2-2*y(:,7).^2);
phi1 = acosd((2.*(y(:,4).*y(:,5)+y(:,6).*y(:,7)))/sind(kap));
phi2 = asind((2.*(y(:,6).*y(:,4)-y(:,5).*y(:,7)))/sind(kap));
if phi1==phi2
phi = phi1;
elseif phi1==180-phi2
phi = phi1;
elseif -phi1==phi2
phi = -phi1;
elseif -phi1==180-phi2
phi = -phi1;
else
disp('Something is wrong with phi')
end
figure (1)
plot(t,phi)
figure (2)
plot(t,kap)
function soln = DynEqn2(t,y,I11,I22,I33,Mx,My,Mz)
w1 = y(1);
w2 = y(2);
w3 = y(3);
eps1 = y(4);
eps2 = y(5);
eps3 = y(6);
eps4 = y(7);
C11 = y(8);
C12 = y(9);
C13 = y(10);
C21 = y(11);
C22 = y(12);
C23 = y(13);
C31 = y(14);
C32 = y(15);
C33 = y(16);
w1_dot = (Mx - w2*w3*(I33-I22))/I11;
w2_dot = (My - w1*w3*(I11-I33))/I22;
w3_dot = (Mz - w1*w2*(I22-I11))/I33;
eps1_dot = .5*(w1*eps4-w2*eps3+w3*eps2);
eps2_dot = .5*(w1*eps3+w2*eps4-w3*eps1);
eps3_dot = .5*(-w1*eps2+w2*eps1+w3*eps4);
eps4_dot = -.5*(w1*eps1+w2*eps2+w3*eps3);
C11_dot = C12*w3-C13*w2;
C12_dot = C13*w1-C11*w3;
C13_dot = C11*w2-C12*w1;
C21_dot = C22*w3-C23*w2;
C22_dot = C23*w1-C21*w3;
C23_dot = C21*w2-C22*w1;
C31_dot = C32*w3-C33*w2;
C32_dot = C33*w1-C31*w3;
C33_dot = C31*w2-C32*w1;
soln = [w1_dot; w2_dot; w3_dot; ...
eps1_dot; eps2_dot; eps3_dot; eps4_dot; ...
C11_dot; C12_dot; C13_dot; C21_dot; C22_dot; C23_dot; C31_dot; C32_dot; C33_dot];
end
My lines where I calculate phi1, phi2, and then the if/else statement to find phi, are what I am struggling with.
I made sure that the variables defined in the function work, so for example, in the command window I typed in 'y(:,4)' and got the correct output. But whenever I try to use this within the functions i.e. 'phi1', it repeatedly outputs an incorrect value of '90.0000' until I stop it.
Where I define the 'N' variable, it is something similar, yet that one works without errors.
Does anyone have any ideas how to amend this issue?
Any help is appreciated, thanks.
Edit: The complete error message is as follows:
Undefined function or variable 'phi'.
Error in HW6_Q1 (line 85)
plot(t,phi)
I figured out my solution with the help from a colleague not on Stack Overflow.
I forgot the ./, which turned my phi into a matrix, rather than a vector which is what I wanted from it.

nnGraph multi-GPU Torch

This question is about making any nnGraph network run on multiple GPUs and not specific to the following network instance
I am trying to train a network which is constructed with nnGraph. The backward diagram is attached. I am trying to run the parallelModel (see code or fig Node 9) in a multi-GPU setting. If I attach the parallel model to a nn.Sequential container and then create a DataParallelTable it works in a multi-GPU setting (without nnGraph). However, after attaching it to nnGraph I get an error. The backward pass works if I train on a single GPU (setting true to false in the if statements), but in a multi-GPU setting I get an error "gmodule.lua:418: attempt to index local 'gradInput' (a nil value)". I think Node 9 in backward pass should run on multiple-GPUs, however that's not happening. Creating DataParallelTable on nnGraph didn't work for me, however I thought atleast putting internal Sequential networks in a DataParallelTable would work. Is there some other way to split the initial data which is being passed to nnGraph so that it runs on multiple-GPUs?
require 'torch'
require 'nn'
require 'cudnn'
require 'cunn'
require 'cutorch'
require 'nngraph'
data1 = torch.ones(4,20):cuda()
data2 = torch.ones(4,10):cuda()
tmodel = nn.Sequential()
tmodel:add(nn.Linear(20,10))
tmodel:add(nn.Linear(10,10))
parallelModel = nn.ParallelTable()
parallelModel:add(tmodel)
parallelModel:add(nn.Identity())
parallelModel:add(nn.Identity())
model = parallelModel
if true then
local function sharingKey(m)
local key = torch.type(m)
if m.__shareGradInputKey then
key = key .. ':' .. m.__shareGradInputKey
end
return key
end
-- Share gradInput for memory efficient backprop
local cache = {}
model:apply(function(m)
local moduleType = torch.type(m)
if torch.isTensor(m.gradInput) and moduleType ~= 'nn.ConcatTable' then
local key = sharingKey(m)
if cache[key] == nil then
cache[key] = torch.CudaStorage(1)
end
m.gradInput = torch.CudaTensor(cache[key], 1, 0)
end
end)
end
if true then
cudnn.fastest = true
cudnn.benchmark = true
-- Wrap the model with DataParallelTable, if using more than one GPU
local gpus = torch.range(1, 2):totable()
local fastest, benchmark = cudnn.fastest, cudnn.benchmark
local dpt = nn.DataParallelTable(1, true, true)
:add(model, gpus)
:threads(function()
local cudnn = require 'cudnn'
cudnn.fastest, cudnn.benchmark = fastest, benchmark
end)
dpt.gradInput = nil
model = dpt:cuda()
end
newmodel = nn.Sequential()
newmodel:add(model)
input1 = nn.Identity()()
input2 = nn.Identity()()
input3 = nn.Identity()()
out = newmodel({input1,input2,input3})
r1 = nn.NarrowTable(1,2)(out)
r2 = nn.NarrowTable(2,2)(out)
f1 = nn.JoinTable(2)(r1)
f2 = nn.JoinTable(2)(r2)
n1 = nn.Sequential()
n1:add(nn.Linear(20,5))
n2 = nn.Sequential()
n2:add(nn.Linear(20,5))
f11 = n1(f1)
f12 = n2(f2)
foutput = nn.JoinTable(2)({f11,f12})
g = nn.gModule({input1,input2,input3},{foutput})
g = g:cuda()
g:forward({data1, data2, data2})
g:backward({data1, data2, data2}, torch.rand(4,10):cuda())
The code in the "if" statements is taken from Facebook's ResNet implementation

Object of type 'closure' is not subsettable - R

I am using R to extract tweets and analyse their sentiment, however when I get to the lines below I get an error saying "Object of type 'closure' is not subsettable"
scores$drink = factor(rep(c("east"), nd))
scores$very.pos = as.numeric(scores$score >= 2)
scores$very.neg = as.numeric(scores$score <= -2)
Full code pasted below
load("twitCred.Rdata")
east_tweets <- filterStream("tweetselnd.json", locations = c(-0.10444, 51.408699, 0.33403, 51.64661),timeout = 120, oauth = twitCred)
tweets.df <- parseTweets("tweetselnd.json", verbose = FALSE)
##function score.sentiment
score.sentiment = function(sentences, pos.words, neg.words, .progress='none')
{
# Parameters
# sentences: vector of text to score
# pos.words: vector of words of postive sentiment
# neg.words: vector of words of negative sentiment
# .progress: passed to laply() to control of progress bar
scores = laply(sentences,
function(sentence, pos.words, neg.words)
{
# remove punctuation
sentence = gsub("[[:punct:]]", "", sentence)
# remove control characters
sentence = gsub("[[:cntrl:]]", "", sentence)
# remove digits?
sentence = gsub('\\d+', '', sentence)
# define error handling function when trying tolower
tryTolower = function(x)
{
# create missing value
y = NA
# tryCatch error
try_error = tryCatch(tolower(x), error=function(e) e)
# if not an error
if (!inherits(try_error, "error"))
y = tolower(x)
# result
return(y)
}
# use tryTolower with sapply
sentence = sapply(sentence, tryTolower)
# split sentence into words with str_split (stringr package)
word.list = str_split(sentence, "\\s+")
words = unlist(word.list)
# compare words to the dictionaries of positive & negative terms
pos.matches = match(words, pos.words)
neg.matches = match(words, neg.words)
# get the position of the matched term or NA
# we just want a TRUE/FALSE
pos.matches = !is.na(pos.matches)
neg.matches = !is.na(neg.matches)
# final score
score = sum(pos.matches) - sum(neg.matches)
return(score)
}, pos.words, neg.words, .progress=.progress )
# data frame with scores for each sentence
scores.df = data.frame(text=sentences, score=scores)
return(scores.df)
}
pos = readLines(file.choose())
neg = readLines(file.choose())
east_text = sapply(east_tweets, function(x) x$getText())
scores = score.sentiment(tweetseldn.json, pos, neg, .progress='text')
scores()$drink = factor(rep(c("east"), nd))
scores()$very.pos = as.numeric(scores()$score >= 2)
scores$very.neg = as.numeric(scores$score <= -2)
# how many very positives and very negatives
numpos = sum(scores$very.pos)
numneg = sum(scores$very.neg)
# global score
global_score = round( 100 * numpos / (numpos + numneg) )
If anyone could help with as to why I'm getting this error it will be much appreciated. Also I've seen other answeres about adding '()' when referring to the variable 'scores' such as scores()$.... but it hasn't worked for me. Thank you.
The changes below got rid of the error:
x <- scores
x$drink = factor(rep(c("east"), nd))
x$very.pos = as.numeric(x$score >= 2)
x$very.neg = as.numeric(x$score <= -2)

For loop inside a function in Lua, Computercraft

I'm learning programming in computercraft (minecraft) and having some trouble with reading some storage cells.
The function that I'm working on shall go through all cells and add together the storage capacity to a variable in a for loop.
This is what I got so far
local cell1 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_2")
local cell2 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_3")
local cell3 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_4")
local cell4 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_5")
local cell5 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_6")
local cell6 = peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_7")
cells = {"cell1", "cell2", "cell3", "cell4", "cell5", "cell6"}
local totStorage
function getTotStorage(table)
for key = 1,6 do
x = table[key]
totStorage = totStorage + x.getMaxEnergyStored()
end
print(totStorage)
end
I get an error on this line
totStorage = totStorage + x.getMaxEnergyStored()
saying "Attempt to call nil".
Any suggestions?
cells = {"cell1", "cell2", "cell3", "cell4", "cell5", "cell6"}
Is shorthand for:
cells = {
-- key value
[1] = "cell1",
[2] = "cell2",
[3] = "cell3",
[4] = "cell4",
[5] = "cell5",
[6] = "cell6"
}
Assuming that your getTotStorage call is similar to below (you didn't post it)
getTotStorage(cells)
In the loop you try to call a method on x which is a string value:
for key = 1,6 do
x = table[key]
totStorage = totStorage + x.getMaxEnergyStored()
end
This is essentially trying to do:
totStorage = totStorage + ("cell1").getMaxEnergyStored()
What you could do is rearrange your code so that the values are the objects returned by peripheral.wrap:
local cells = {
peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_2"),
peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_3"),
peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_4"),
peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_5"),
peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_6"),
peripheral.wrap("tile_thermalexpansion_cell_reinforced_name_7"),
}
function getTotStorage(t)
local totStorage = 0
for i,v in ipairs(t) do
totStorage = totStorage + v.getMaxEnergyStored()
end
print(totStorage)
end
A few observations:
Use local when you can (i.e. totStorage) to limit the scope of a variable (no need to have a loop counter as a global)
Don't name variables that collide with the standard Lua library (i.e. string, table, math)
ipairs is a better way to loop through a sequence