w4nderlust wrote: > Il giorno 06/gen/2011, alle ore 22.27, David Bateman ha scritto: > > >> w4nderlust wrote: >> >>> Hello everyone. >>> >>> I'm still working with sparse matrices in oct-file, but i've got some >>> problems: i'm doing some multithread and as the octave libraries >>> revealed to be not really thread safe (some unexpected crashed ofter >>> repeating executions) i did the dirty work by hand: i copied the 3 >>> vectors of the matrix B (the input matrix) and copied the full matrix >>> A into a vector. >>> >> If you do something like >> >> const SparseMatrix a = args(0).sparse_matrix_value (); >> const *double adata = a.data(); >> const *octave_idx_type acidx = a.cidx(); >> const *octave_idx_type aridx = a.ridx(); >> >> you can clean up a lot of the issues I believe you were having. As the >> rest of you code will then just work on these pointers there is no >> reason that the code shouldn't be thread-safe. However >> > > I'm trying right now, but when i was using the multithread on the nonsparse > version of this project (so using the octve matrix objects) it crashed when > repeating 1000 executions continuously, but when i modifidies to use simble > double * as matrix class replacement it worked fine. That's why i'm doing all > this :) > I think you missed my point. The above gives you double* and octave_idx_type* pointer to the underlying data structures of the Octave sparse matrix that you can manipulate directly. No need to copy from the matrix to a *double pointer.
> I think you are talking about this: > http://www.network-theory.co.uk/docs/octave3/octave_204.html 20.1.1 > I was talking about the oct-file part ( > http://www.gnu.org/software/octave/doc/interpreter/Sparse-Matrices-in-Oct_002dFiles.html > ). The two sections were written together. If you don't know how sparse matrices are used in the octave interpreter its perhaps permature to read the section on using them in oct-files. So section 21 of the manual should be read before the appendix. > I think is lacking in at least 2 points, i write them here not to contrast > your opinion, but simply because maybe someone would agree and improve the > documentation (maybe when i finish this project i could do something for what > i think i understand well > I wrote these sections, and although these were written rapidly, if they aren't read independently, and other basic concepts of oct-files are understood they should be understandable. Yes they might be improved, but I think you need to use sparse matrices a bit more in Octave first as there seems to be some basic points you're still missing. > - the example in 20.1.1 is confusing with the example in > http://www.gnu.org/software/octave/doc/interpreter/Creating-Sparse-Matrices-in-Oct_002dFiles.html#Creating-Sparse-Matrices-in-Oct_002dFiles > (the first one) as the cidx vector is completely different 8and i think it > is wrong here). > What is proposed in 20.1.2 (21.1.2 in the manual of 3.3.x and soon to be 3.4.0) rather than 20.1.1. The data structure cidx, ridx of a sparse matrix are not exposed in the interpreter of Octave and so working with them directly is not an option. What is proposed in section 2.1.2 is to create 3 vectors representing the triplets (row, col, val) that are then internally converted to cidx, ridx, data in an fairly efficient manner. In oct-files you have access to cidx, ridx, data and working directly with them is more efficient and trying to work on a sparse matrix in an oct-file directly with (row, col, val) triplets is going to be extremely slow.. This explains the difference between the two. If you want to do the same thing that the example in 21.1.2 suggests in a oct-file then do something like OCTAVE_LOCAL_BUFFER (double, val, nnz) OCTAVE_LOCAL_BUFFER (octave_idx_type, rows, nnz) OCTAVE_LOCAL_BUFFER (octave_idx_type, cols, nnz) for (octave_idx_type i = 0; i < nnz; i++) { val[i] = ....; rows[i] = ....; cols[i] = ....; } SparseMatix c (rows, cols, val) instead. However working directly with cidx, ridx and data will save you a copying the matrix in memory and will be more efficient. > - the usage page is really poor, the only method shown > sparse_bool_matrix_value () . I have no idea what you mean by "usage page".. I presume you mean section A1.6.3. This section as it says is how to use the sparse matrix type in oct-files themselves and concerns only the interface from the octave_value type and back again so that you can deal with the data. Section A1.6.2 had already discussed how to deal with the data in the sparse matrices themselves.. Section A1.6.3 has the example octave_value_list retval; SparseMatrix sm = args(0).sparse_matrix_value (); SparseComplexMatrix scm = args(1).sparse_complex_matrix_value (); SparseBoolMatrix sbm = args(2).sparse_bool_matrix_value (); ... retval(2) = sbm; retval(1) = scm; retval(0) = sm; and all three types of sparse matrices are treated.. I can accept criticism but at least make it valid. > All he other methods are present in the octave-forge documentation but > there's no description for each one and some parameters are really obscure to > me (for example the boolean value at the end of the constructor with the 3 > vectors) > > I presume by the octave-forge documentation you mean the doxygen pages at http://octave.sourceforge.net/doxygen/html/class_sparse_matrix.html This is created from the octave source code directly by doxygen and has no more information than the source code itself. By boolean value at the end of the constructor I presume you mean the constructor given by http://octave.sourceforge.net/doxygen/html/class_sparse_matrix.html#3d38fab78c54c461739f46ae8e7196ff where the boolean value is called "sum_terms". Nothing stops you (row,col,val) triplets from duplicating (row,col) values. In this case you have two choices. Keep only the second value or sum the values with the same (row,col) values which is the default.. Its kind of implicit in the variable name "sum_terms" I would have thought.. Or you might have figured it out by reading "help sparse" in the section <quote> Note: if multiple values are specified with the same I, J indices, the corresponding values in S will be added. The following are all equivalent: s = sparse (i, j, s, m, n) s = sparse (i, j, s, m, n, "summation") s = sparse (i, j, s, m, n, "sum") Given the option "unique". if more than two values are specified for the same I, J indices, the last specified value will be used. </quote> Sure it might be clearer, but no one has complained about this point yet. The octave code is pretty clear and so you shouldn't hesitate to jump into it directly for more info. > >> I see two solutions. >> >> 1) Precalculate the number of non-zero elements per-column. That is, in >> the code block I sent you for spmaxmin_new.cc calculate the output cidx >> at the same time you calculate nel, rather than in the second loop. If >> you first save the number of non-zero elements to ccidx you can even >> thread this. For example (with code that might be threaded, without the >> threading itself) >> >> c.xcidx (0) = 0; >> for (octave_idx_type i = 0; i < rowsA; i++) >> { >> // From here on this code could be threaded >> octave_idx_type kk = 0 >> >> for(octave_idx_type j = 0; j < colsB; j++) >> { >> if (b.cidx(j) != b.cidx(j+1)) >> kk++; >> else >> { >> for (octave_idx_type k = b.cidx(j); >> k <= (b.cidx(j+1) - 1); k++) >> { >> if (a(i, b.ridx(k)) != 0) >> { >> kk++; >> break; >> } >> } >> } >> } >> c.xcidx(i+1) = kk; >> } >> >> // Now that we've calculated the number of elements per column of >> the output matrix in code >> // that might be threaded, correct the indexing (Can't be threaded) >> for (octave_idx_type i = 0; i < rowsA; i++) >> c.xcidx(i+1) += c.xcidx(i); >> >> octave_idx_type nel = c.xcidx(rowsA); >> >> It might not be profitable to thread the above and it could be >> simplified to >> >> octave_idx_type nel = 0; >> >> c.xcidx(0) = 0; >> for (octave_idx_type i = 0; i < rowsA; i++) >> { >> for(octave_idx_type j = 0; j < colsB; j++) >> { >> if (b.cidx(j) != b.cidx(j+1)) >> nel++; >> else >> { >> for (octave_idx_type k = b.cidx(j); >> k <= (b.cidx(j+1) - 1); k++) >> { >> if (a(i, b.ridx(k)) != 0) >> { >> nel++; >> break; >> } >> } >> } >> } >> c.xcidx(i+1) = nel; >> } >> >> You can then uses c.xcidx in your thread_function to index correctly >> into c.xridx and c.xdata. >> >> >> 2) You could create N different sparse matrices, one per thread, and >> then concatenate them together with the concat method. This will >> probably be slower and more memory hungry than the above so I won't >> develop this idea further. >> >> > > I think the first is the wa i will follow. Mabe i'll try to execute my test > adding directly to c(i,j) for each thread (this makes the code really cleaner > for the threads) and not working directly on the c index vectors. If this > still gives me creashes on multiple executions, i'll try to wark the way you > described on point 1. > I reaIly wouldn't suggest working directly with c(i,j) as writing to c(i,j) will essentially move the data in the matrix to to make way for the new data. If you want to work with c(i,j) then the loops should be in this order for (octave_idx_type i = 0; i < m; i++) for (octave_idx_type j = 0; j < n; j++) c(i,j) = ....; and not the reverse or any out of order row,col calculation as this will allow the new elements to be written directly to the end of the ridx and data arrays. However, to just simply search the matrix to ensure that such a copy isn't needed and modifying all the elements of cidx implied by a write to c(i,j) is a O(n) operation, whereas working directly with an element using cidx,ridx,data should be O(1). So I know which way I'd prefer to write my code. D. ------------------------------------------------------------------------------ Gaining the trust of online customers is vital for the success of any company that requires sensitive data to be transmitted over the Web. Learn how to best implement a security strategy that keeps consumers' information secure and instills the confidence they need to proceed with transactions. http://p.sf.net/sfu/oracle-sfdevnl _______________________________________________ Octave-dev mailing list Octave-dev@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/octave-dev