I am trying to learn array reduction techniques in system verilog. Wrote below module:
module main;
localparam [7:0]PARAM_ARR0[3:0] = '{8'h1,8'h3,8'h4,8'h0};
localparam [3:0]PARAM_ARR1[7:0] = '{4'h3,4'h2,4'h2,4'h2,4'h1,4'h1,4'h1,4'h1};
int s = 0;
logic [7:0]arr0[3:0] = '{8'h1,8'h3,8'h4,8'h0};
logic [3:0]arr1[7:0] = '{4'h3,4'h2,4'h2,4'h2,4'h1,4'h1,4'h1,4'h1};
initial begin
//s = int'(PARAM_ARR0.sum() with (item.index<int'(PARAM_ARR1[0])?item:0));
//$display("sum0 = %0d",s);
//s = int'(PARAM_ARR0.sum() with (item.index<int'(PARAM_ARR1[4])?item:0));
//$display("sum1 = %0d",s);
s = int'(arr0.sum() with (item.index<int'(arr1[0])?item:0));
$display("sum0 = %0d",s);
s = int'(arr0.sum() with (item.index<int'(arr1[4])?item:0));
$display("sum1 = %0d",s);
s = int'(arr0.sum() with (item.index<int'(arr1[7])?item:0));
$display("sum2 = %0d",s);
end
endmodule
If I uncomment the first 4 lines after initial (array reduction on 2D array of parameters), VCS is throwing compile errors like below. Is array methods not applicable on parameter arrays?
Error-[XMRE] Cross-module reference resolution error
../../test_param_array_sum.sv, 10
Error found while trying to resolve cross-module reference.
token 'sum'. Originating module 'main'.
Source info: PARAM_ARR0.sum(item) with (((item.index < int'(4'b1))
? item : 0))
Error-[IND] Identifier not declared
../../test_param_array_sum.sv, 10
Identifier 'item' has not been declared yet. If this error is not expected,
please check if you have set `default_nettype to none.
One more doubt is that when I simulate the code in VCS as is given above, I'm getting below results:
sum0 = 1
sum1 = 4
sum2 = 8
I was expecting results to be 0, 4 and 7 respectively. Because I was trying to get the sum of all elements in arr0 whose index is less than arr1[0] (1), arr1[4] (2), arr1[7] (3) respectively.
Thanks
This works for me in Questa 2019.2. You may have to talk to your EDA AE about what's wrong. Serge's recommendation for using dynamic arrays works: https://www.edaplayground.com/x/26RL
Also, looks like your code is giving the results you expected in Questa.
# Loading sv_std.std
# Loading work.main(fast)
# run -all
# sum0 = 0
# sum1 = 4
# sum0 = 0
# sum1 = 4
# sum2 = 7
# quit -f
# End time: 11:17:11 on May 23,2019, Elapsed time: 0:00:21
# Errors: 0, Warnings: 0
Related
I'm currently trying to create a Sudoku without help but i'm stuck on one issue.
def play():
global myinput
global column_rdm
sudoku_col = [[] for _ in range(9)]
for i in range(9):
sudoku_col[i].append(0)
h = 1
try:
while h < 10:
rdm_list = random.sample(range(1, 10), 9)
test_var = 0
for j in range(9):
if rdm_list[j] not in sudoku_col[j]:
test_var += 1
if test_var == 9:
for rdm_number, g in rdm_list, range(9):
sudoku_col[g].append(rdm_number)
# Input the values found in the sudoku
column_rdm = f"{rdm_number}"
myinput = Input(h, g+1)
myinput.value_def(column_rdm) # end
h += 1
update()
# except Exception as e:
# print("Erreur dans la création du Sudoku")
finally:
print(h)
Here the function that should create my Sudoku. I create random lists of 9 numbers which will be my sudoku raws, and i check if each item of those lists is already present in its column with my "sudoku_col". If the test is OK (that is, test_var == 9), then I add this raw to my template. If not, I create a new random list and let it complete the test again. I do that until I have 9 raws (h < 10).
However, the code stops at line "for rdm_number, g in rdm_list, range(9):" due to a ValueError. That should not happen, because rdm_list and range(9) have the same lenght and each item in both lists should be iterated correctly. What am I missing here ?
Thank you for your time
It should be
for rdm_number, g in zip(rdm_list, range(9)):
what you are doing is the same as
for rdm_number, g in (rdm_list, range(9)):
which creates a tuple with two items that you iterate over, you can see that happen if you do this (it will print out whatever is the rdm_list and range(0, 9)):
for sth in rdm_list, range(9):
print(sth)
also while h < 10 can just be replaced with for h in range(9): and you don't need to increase any variables and for loops are faster.
Another improvement would be to do this (instead of using the range and accessing values by index):
for rdm, s_col in zip(rdm_list, sudoku_col):
if rdm not in s_col:
test_var += 1
Also this:
sudoku_col = [[] for _ in range(9)]
for i in range(9):
sudoku_col[i].append(0)
can easily be reduced to
sudoku_col = [[0] for _ in range(9)]
Again you shouldn't use range to access values by using index, you should iterate over the values like this: for value in iterable:, instead of for index in range(len(iterable)), if you also need the index then use this: for index, value in enumerate(iterable):
The following code generates an cell array Index [1x29], where each cell is an array [29x6]:
for i = 1 : size(P1_cell,1)
for j = 1 : size(P1_cell,2)
[Lia,Lib] = ismember(P1_cell{i,j},PATTERNS_FOR_ERANOS_cell{1},'rows');
Index1(i,j) = Lib % 29x6
end
Index{i} = Index1; % 1x29
end
How can I find the nonzero values in Index array?, i.e. generate an array with the number of non-zero values in each row of the Index1 array. I tried the following loop, but it doesn't work, it creates conflict with the previous one:
for i = 1 : length(Index)
for j = 1 : length(Index)
Non_ceros = length(find(Index{:,i}(j,:))); %% I just need the length of the find function output
end
end
I need help, Thanks in advance.
The nnz() (number of non-zeros) function can be used to evaluate the number of non-zero elements. To obtain the specific positive values you can index the array by using the indices returned by the find() function. I used some random test data but it should work for 29 by 6 sized arrays as well.
%Random test data%
Index{1} = [5 2 3 0 zeros(1,25)];
Index{2} = [9 2 3 1 zeros(1,25)];
Index{3} = [5 5 5 5 zeros(1,25)];
%Initializing and array to count the number of zeroes%
Non_Zero_Counts = zeros(length(Index),1);
for Row_Index = 1: length(Index)
%Evaluating the number of positive values%
Array = Index{Row_Index};
Non_Zero_Counts(Row_Index) = nnz(Array);
%Retrieving the positive values%
Positive_Indices = find(Array);
PositiveElements{Row_Index} = Array(Positive_Indices);
disp(Non_Zero_Counts(Row_Index) + " Non-Zero Elements ");
disp(PositiveElements{Row_Index});
end
Ran using MATLAB R2019b
for i = 1 : length(Index)
for j = 1 : length(Index)
Non_ceros(i,j) = nnz(Index{:,i}(j,:));
end
end
Suppose I have an array of 100_000 records ( this is Ruby code, but any language will do)
ary = ['apple','orange','dog','tomato', 12, 17,'cat','tiger' .... ]
results = []
I can only make random calls to the array ( I cannot traverse it in any way)
results << ary.sample
# in ruby this will pull a random record from the array, and
# push into results array
How many random calls like that, do I need to make, to get least 80% of records from ary. Or expressed another way - what should be the size of results so that results.uniq will contain around 80_000 records from ary.
From my rusty memory of Stats class in college, I think it's needs to be 2*result set size = or around 160_000 requests ( assuming random function is random, and there is no some other underlying issue) . My testing seems to confirm this.
ary = [*1..100_000];
result = [];
160_000.times{result << ary.sample};
result.uniq.size # ~ 80k
This is stats, so we are talking about probabilities, not guaranteed results. I just need a reasonable guess.
So the question really, what's the formula to confirm this?
I would just perform a quick simulation study. In R,
N = 1e5
# Simulate 300 times
s = replicate(300, sample(x = 1:N, size = 1.7e5, replace = TRUE))
Now work out when you hit your target
f = function(i) which(i == unique(i)[80000])[1]
stats = apply(s, 2, f)
To get
summary(stats)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 159711 160726 161032 161037 161399 162242
So in 300 trials, the maximum number of simulations needed was 162242 with an average number of 161032.
With Fisher-Yates shuffle you could get 80K items from exactly 80K random calls
Have no knowledge of Ruby, but looking at https://gist.github.com/mindplace/3f3a08299651ebf4ab91de3d83254fbc and modifying it
def shuffle(array, counter)
#counter = array.length - 1
while counter > 0
# item selected from the unshuffled part of array
random_index = rand(counter)
# swap the items at those locations
array[counter], array[random_index] = array[random_index], array[counter]
# de-increment counter
counter -= 1
end
array
end
indices = [0, 1, 2, 3, ...] # up to 99999
counter = 80000
shuffle(indices, 80000)
i = 0
while counter > 0
res[i] = ary[indices[i]]
counter -= 1
i += 1
UPDATE
Packing sampled indices into custom RNG (bear with me, know nothing about Ruby)
class FYRandom
_indices = indices
_max = 80000
_idx = 0
def rand()
if _idx > _max
return -1.0
r = _indices[idx]
_idx += 1
return r.to_f / max.to_f
end
end
And code for sample would be
rng = FYRandom.new
results << ary.sample(random: rng)
I am trying to spawn and evaluate expressions over different processes. The expressions contain local parts of distributed arrays, and this seems to create problems. For example,
addprocs(2)
x = [i for i = 1:10]
foo = #spawnat 2 quote
out = x[1]
for i = 2:5
out += x[i]
end
out
end
eval(fetch(foo))
gives, as expected,
Out [ ]: 15
However, if I try to replace the vector x with a distributed array dx and use only the local chunk in the expression, I get the following error.
# Construct a distributed array dx = [1,2,3,4,5,6,7,8,9,10] #
dx = DArray(I->[i for i in I[1]], (10, ))
dfoo = #spawnat 2 quote
out = localpart(dx)[1]
for i = 2:5
out += localpart(dx)[i]
end
out
end
eval(fetch(dfoo))
Out []: ERROR: BoundsError()
while loading In[9], in expression starting on line 9
in getindex at array.jl:246
in anonymous at In[9]:2
I got the feeling that the problem is the localpart() which is not recognized when the expression is evaluated.
Am I right?
Is there a way around this issue?
Thank you
Here its the quote function that spawns at 2, not the evaluation itself. its like a misusage of spawnat macro.
look at this:
addprocs(2)
foo = #spawnat 2 quote
myid()
end
eval(fetch(foo)) # => 1
And to calculate sum over distributed array: (there is nothing to do with #spawnat)
# Construct a distributed array dx = [1,2,3,4,5,6,7,8,9,10] #
dx = DArray(I->[i for i in I[1]], (10, ))
dfoo = #spawnat 2 quote
sum(localpart(dx))
end
eval(fetch(dfoo))==sum(localpart(dx)) # => true
i was trying to store my simulation output inside an array. I have written the following code:
nsim=50
res=array(0,c(nsim,20,20))
for(i in 1:nsim) {
cat("simul=",i,"\n")
simulated = NULL
stik.simulated = NULL
simulated = rpp(....)
stik.simulated = STIKhat(....)
# from stik.simulated we will get $khat and $Ktheo and
# the dimension of stik.simulated$Khat-stik.simulated$Ktheo is 20 x 20
res[i,,] = stik.simulated$Khat - stik.simulated$Ktheo
}
But whenever the function is trying to store the output inside an array, I get the following error:
simul= 1
Xrange is 20 40
Yrange is -20 20
Doing quartic kernel
Error in res[, , i] = stik.simulated$Khat - stik.simulated$Ktheo :
subscript out of bounds
seeking your help. Thanks.
I think you need to organize your code to avoid such errors. I assume you are using package stpp.
First You create, a function which generate the matrix of each iteration; Try to test your function with many values.
stick_diff <- function(u,v){
u <- seq(0,u,by=1)
v <- seq(0,v,by=1)
simulated <- rpp(...) ## call here rpp with right parameters
stik <- STIKhat(xyt=simulated$xyt,
dist=u, times=v, ...)
stik$Khat-stik$Ktheo ## !! here if u#v you will have recycling!
}
Once you are sure of your function you call it the loop, with right dimensions.
nsim <- 50
u <- 20
res=array(0,c(nsim,u,u))
for(i in 1:nsim)
res[i,,] <- stick_diff(i,u,u)