This file is indexed.

/usr/include/viennacl/forwards.h is in libviennacl-dev 1.5.2-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
#ifndef VIENNACL_FORWARDS_H
#define VIENNACL_FORWARDS_H

/* =========================================================================
   Copyright (c) 2010-2014, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.
   Portions of this software are copyright by UChicago Argonne, LLC.

                            -----------------
                  ViennaCL - The Vienna Computing Library
                            -----------------

   Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at

   (A list of authors and contributors can be found in the PDF manual)

   License:         MIT (X11), see file LICENSE in the base directory
============================================================================= */


/** @file viennacl/forwards.h
    @brief This file provides the forward declarations for the main types used within ViennaCL
*/

/**
 @mainpage Source Code Documentation for ViennaCL 1.5.2

 This is the source code documentation of ViennaCL. Detailed information about the functions in ViennaCL can be found here.

 For a general overview over the types and functionality provided by ViennaCL, please refer to the file doc/viennacl.pdf

*/


//compatibility defines:
#ifdef VIENNACL_HAVE_UBLAS
  #define VIENNACL_WITH_UBLAS
#endif

#ifdef VIENNACL_HAVE_EIGEN
  #define VIENNACL_WITH_EIGEN
#endif

#ifdef VIENNACL_HAVE_MTL4
  #define VIENNACL_WITH_MTL4
#endif

#include <cstddef>
#include <cassert>
#include <string>

#include "viennacl/meta/enable_if.hpp"

/** @brief Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them. */
namespace viennacl
{
  typedef std::size_t                                       vcl_size_t;
  typedef std::ptrdiff_t                                    vcl_ptrdiff_t;


  /** @brief A tag class representing assignment */
  struct op_assign {};
  /** @brief A tag class representing inplace addition */
  struct op_inplace_add {};
  /** @brief A tag class representing inplace subtraction */
  struct op_inplace_sub {};

  /** @brief A tag class representing addition */
  struct op_add {};
  /** @brief A tag class representing subtraction */
  struct op_sub {};
  /** @brief A tag class representing multiplication by a scalar */
  struct op_mult {};
  /** @brief A tag class representing matrix-vector products and element-wise multiplications*/
  struct op_prod {};
  /** @brief A tag class representing matrix-matrix products */
  struct op_mat_mat_prod {};
  /** @brief A tag class representing division */
  struct op_div {};
  /** @brief A tag class representing the power function */
  struct op_pow {};

  /** @brief A tag class representing element-wise binary operations (like multiplication) on vectors or matrices */
  template <typename OP>
  struct op_element_binary {};

  /** @brief A tag class representing element-wise unary operations (like sin()) on vectors or matrices */
  template <typename OP>
  struct op_element_unary {};

  /** @brief A tag class representing the modulus function for integers */
  struct op_abs {};
  /** @brief A tag class representing the acos() function */
  struct op_acos {};
  /** @brief A tag class representing the asin() function */
  struct op_asin {};
  /** @brief A tag class representing the atan() function */
  struct op_atan {};
  /** @brief A tag class representing the atan2() function */
  struct op_atan2 {};
  /** @brief A tag class representing the ceil() function */
  struct op_ceil {};
  /** @brief A tag class representing the cos() function */
  struct op_cos {};
  /** @brief A tag class representing the cosh() function */
  struct op_cosh {};
  /** @brief A tag class representing the exp() function */
  struct op_exp {};
  /** @brief A tag class representing the fabs() function */
  struct op_fabs {};
  /** @brief A tag class representing the fdim() function */
  struct op_fdim {};
  /** @brief A tag class representing the floor() function */
  struct op_floor {};
  /** @brief A tag class representing the fmax() function */
  struct op_fmax {};
  /** @brief A tag class representing the fmin() function */
  struct op_fmin {};
  /** @brief A tag class representing the fmod() function */
  struct op_fmod {};
  /** @brief A tag class representing the log() function */
  struct op_log {};
  /** @brief A tag class representing the log10() function */
  struct op_log10 {};
  /** @brief A tag class representing the sin() function */
  struct op_sin {};
  /** @brief A tag class representing the sinh() function */
  struct op_sinh {};
  /** @brief A tag class representing the sqrt() function */
  struct op_sqrt {};
  /** @brief A tag class representing the tan() function */
  struct op_tan {};
  /** @brief A tag class representing the tanh() function */
  struct op_tanh {};

  /** @brief A tag class representing the (off-)diagonal of a matrix */
  struct op_matrix_diag {};

  /** @brief A tag class representing a matrix given by a vector placed on a certain (off-)diagonal */
  struct op_vector_diag {};

  /** @brief A tag class representing the extraction of a matrix row to a vector */
  struct op_row {};

  /** @brief A tag class representing the extraction of a matrix column to a vector */
  struct op_column {};

  /** @brief A tag class representing inner products of two vectors */
  struct op_inner_prod {};

  /** @brief A tag class representing the 1-norm of a vector */
  struct op_norm_1 {};

  /** @brief A tag class representing the 2-norm of a vector */
  struct op_norm_2 {};

  /** @brief A tag class representing the inf-norm of a vector */
  struct op_norm_inf {};

  /** @brief A tag class representing the Frobenius-norm of a matrix */
  struct op_norm_frobenius {};

  /** @brief A tag class representing transposed matrices */
  struct op_trans {};

  /** @brief A tag class representing sign flips (for scalars only. Vectors and matrices use the standard multiplication by the scalar -1.0) */
  struct op_flip_sign {};

  //forward declaration of basic types:
  template<class TYPE>
  class scalar;

  template <typename LHS, typename RHS, typename OP>
  class scalar_expression;

  template <typename SCALARTYPE>
  class entry_proxy;

  template <typename LHS, typename RHS, typename OP>
  class vector_expression;

  template<class SCALARTYPE, unsigned int ALIGNMENT>
  class vector_iterator;

  template<class SCALARTYPE, unsigned int ALIGNMENT>
  class const_vector_iterator;

  template<typename SCALARTYPE>
  class implicit_vector_base;

  template <typename SCALARTYPE>
  class zero_vector;

  template <typename SCALARTYPE>
  class unit_vector;

  template <typename SCALARTYPE>
  class one_vector;

  template <typename SCALARTYPE>
  class scalar_vector;

  template<class SCALARTYPE, typename SizeType = vcl_size_t, typename DistanceType = vcl_ptrdiff_t>
  class vector_base;

  template<class SCALARTYPE, unsigned int ALIGNMENT = 1>
  class vector;

  template <typename ScalarT>
  class vector_tuple;

  //the following forwards are needed for GMRES
  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
  void copy(CPU_ITERATOR const & cpu_begin,
            CPU_ITERATOR const & cpu_end,
            vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin);

  template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
  void copy(const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_begin,
            const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_end,
            vector_iterator<SCALARTYPE, ALIGNMENT_DEST> gpu_dest_begin);

  template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
  void copy(const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_begin,
            const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_end,
            const_vector_iterator<SCALARTYPE, ALIGNMENT_DEST> gpu_dest_begin);

  template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
  void fast_copy(const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_begin,
                 const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_end,
                 CPU_ITERATOR cpu_begin );

  template <typename CPU_ITERATOR, typename SCALARTYPE, unsigned int ALIGNMENT>
  void fast_copy(CPU_ITERATOR const & cpu_begin,
                  CPU_ITERATOR const & cpu_end,
                  vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin);


  /** @brief Tag class for indicating row-major layout of a matrix. Not passed to the matrix directly, see row_major type. */
  struct row_major_tag {};
  /** @brief Tag class for indicating column-major layout of a matrix. Not passed to the matrix directly, see row_major type. */
  struct column_major_tag {};

  /** @brief A tag for row-major storage of a dense matrix. */
  struct row_major
  {
    typedef row_major_tag         orientation_category;

    /** @brief Returns the memory offset for entry (i,j) of a dense matrix.
    *
    * @param i   row index
    * @param j   column index
    * @param num_cols  number of entries per column (including alignment)
    */
    static vcl_size_t mem_index(vcl_size_t i, vcl_size_t j, vcl_size_t /* num_rows */, vcl_size_t num_cols)
    {
      return i * num_cols + j;
    }
  };

  /** @brief A tag for column-major storage of a dense matrix. */
  struct column_major
  {
    typedef column_major_tag         orientation_category;

    /** @brief Returns the memory offset for entry (i,j) of a dense matrix.
    *
    * @param i   row index
    * @param j   column index
    * @param num_rows  number of entries per row (including alignment)
    */
    static vcl_size_t mem_index(vcl_size_t i, vcl_size_t j, vcl_size_t num_rows, vcl_size_t /* num_cols */)
    {
      return i + j * num_rows;
    }
  };

  struct row_iteration;
  struct col_iteration;

  template <typename LHS, typename RHS, typename OP>
  class matrix_expression;

  //
  // Matrix types:
  //

  template<class SCALARTYPE, typename F = row_major, typename SizeType = vcl_size_t, typename DistanceType = vcl_ptrdiff_t>
  class matrix_base;

  template <class SCALARTYPE, typename F = row_major, unsigned int ALIGNMENT = 1>
  class matrix;

  template<typename SCALARTYPE>
  class implicit_matrix_base;

  template <class SCALARTYPE>
  class identity_matrix;

  template <class SCALARTYPE>
  class zero_matrix;

  template <class SCALARTYPE>
  class scalar_matrix;

  template<class SCALARTYPE, unsigned int ALIGNMENT = 1>
  class compressed_matrix;

  template<class SCALARTYPE>
  class compressed_compressed_matrix;


  template<class SCALARTYPE, unsigned int ALIGNMENT = 128>
  class coordinate_matrix;

  template<class SCALARTYPE, unsigned int ALIGNMENT = 1>
  class ell_matrix;

  template<class SCALARTYPE, unsigned int ALIGNMENT = 1>
  class hyb_matrix;

  template<class SCALARTYPE, unsigned int ALIGNMENT = 1>
  class circulant_matrix;

  template<class SCALARTYPE, unsigned int ALIGNMENT = 1>
  class hankel_matrix;

  template<class SCALARTYPE, unsigned int ALIGNMENT = 1>
  class toeplitz_matrix;

  template<class SCALARTYPE, unsigned int ALIGNMENT = 1>
  class vandermonde_matrix;

  //
  // Proxies:
  //
  template <typename SizeType = vcl_size_t, typename DistanceType = std::ptrdiff_t>
  class basic_range;

  typedef basic_range<>  range;

  template <typename SizeType = vcl_size_t, typename DistanceType = std::ptrdiff_t>
  class basic_slice;

  typedef basic_slice<>  slice;

  template <typename VectorType>
  class vector_range;

  template <typename VectorType>
  class vector_slice;

  template <typename MatrixType>
  class matrix_range;

  template <typename MatrixType>
  class matrix_slice;


  /** @brief Helper struct for checking whether a type is a host scalar type (e.g. float, double) */
  template <typename T>
  struct is_cpu_scalar
  {
    enum { value = false };
  };

  /** @brief Helper struct for checking whether a type is a viennacl::scalar<> */
  template <typename T>
  struct is_scalar
  {
    enum { value = false };
  };

  /** @brief Helper struct for checking whether a type represents a sign flip on a viennacl::scalar<> */
  template <typename T>
  struct is_flip_sign_scalar
  {
    enum { value = false };
  };

  /** @brief Helper struct for checking whether the provided type represents a scalar (either host, from ViennaCL, or a flip-sign proxy) */
  template <typename T>
  struct is_any_scalar
  {
    enum { value = (is_scalar<T>::value || is_cpu_scalar<T>::value || is_flip_sign_scalar<T>::value )};
  };

  /** @brief Checks for a type being either vector_base or implicit_vector_base */
  template<typename T>
  struct is_any_vector { enum { value = 0 }; };

  /** @brief Checks for either matrix_base or implicit_matrix_base */
  template<typename T>
  struct is_any_dense_matrix { enum { value = 0 }; };

  /** @brief Helper class for checking whether a matrix has a row-major layout. */
  template <typename T>
  struct is_row_major
  {
    enum { value = false };
  };

  /** @brief Helper class for checking whether a matrix is a compressed_matrix (CSR format) */
  template <typename T>
  struct is_compressed_matrix
  {
    enum { value = false };
  };

  /** @brief Helper class for checking whether a matrix is a coordinate_matrix (COO format) */
  template <typename T>
  struct is_coordinate_matrix
  {
    enum { value = false };
  };

  /** @brief Helper class for checking whether a matrix is an ell_matrix (ELL format) */
  template <typename T>
  struct is_ell_matrix
  {
    enum { value = false };
  };

  /** @brief Helper class for checking whether a matrix is a hyb_matrix (hybrid format: ELL plus CSR) */
  template <typename T>
  struct is_hyb_matrix
  {
    enum { value = false };
  };

  /** @brief Helper class for checking whether the provided type is one of the sparse matrix types (compressed_matrix, coordinate_matrix, etc.) */
  template <typename T>
  struct is_any_sparse_matrix
  {
    enum { value = false };
  };


  /** @brief Helper class for checking whether a matrix is a circulant matrix */
  template <typename T>
  struct is_circulant_matrix
  {
    enum { value = false };
  };

  /** @brief Helper class for checking whether a matrix is a Hankel matrix */
  template <typename T>
  struct is_hankel_matrix
  {
    enum { value = false };
  };

  /** @brief Helper class for checking whether a matrix is a Toeplitz matrix */
  template <typename T>
  struct is_toeplitz_matrix
  {
    enum { value = false };
  };

  /** @brief Helper class for checking whether a matrix is a Vandermonde matrix */
  template <typename T>
  struct is_vandermonde_matrix
  {
    enum { value = false };
  };

  /** @brief Helper class for checking whether the provided type is any of the dense structured matrix types (circulant, Hankel, etc.) */
  template <typename T>
  struct is_any_dense_structured_matrix
  {
    enum { value = viennacl::is_circulant_matrix<T>::value || viennacl::is_hankel_matrix<T>::value || viennacl::is_toeplitz_matrix<T>::value || viennacl::is_vandermonde_matrix<T>::value };
  };


  enum memory_types
  {
    MEMORY_NOT_INITIALIZED
    , MAIN_MEMORY
    , OPENCL_MEMORY
    , CUDA_MEMORY
  };

  /** @brief Exception class in case of memory errors */
  class memory_exception : public std::exception
  {
  public:
    memory_exception() : message_() {}
    memory_exception(std::string message) : message_("ViennaCL: Internal memory error: " + message) {}

    virtual const char* what() const throw() { return message_.c_str(); }

    virtual ~memory_exception() throw() {}
  private:
    std::string message_;
  };

  class cuda_not_available_exception : public std::exception
  {
  public:
    cuda_not_available_exception() : message_("ViennaCL was compiled without CUDA support, but CUDA functionality required for this operation.") {}

    virtual const char* what() const throw() { return message_.c_str(); }

    virtual ~cuda_not_available_exception() throw() {}
  private:
    std::string message_;
  };


  class context;

  namespace tools
  {
    //helper for matrix row/col iterators
    //must be specialized for every viennacl matrix type
    /** @brief Helper class for incrementing an iterator in a dense matrix. */
    template <typename ROWCOL, typename MATRIXTYPE>
    struct MATRIX_ITERATOR_INCREMENTER
    {
      typedef typename MATRIXTYPE::ERROR_SPECIALIZATION_FOR_THIS_MATRIX_TYPE_MISSING          ErrorIndicator;

      static void apply(const MATRIXTYPE & /*mat*/, unsigned int & /*row*/, unsigned int & /*col*/) {}
    };
  }

  namespace linalg
  {
#if !defined(_MSC_VER) || defined(__CUDACC__)

    template<class SCALARTYPE, unsigned int ALIGNMENT>
    void convolve_i(viennacl::vector<SCALARTYPE, ALIGNMENT>& input1,
                    viennacl::vector<SCALARTYPE, ALIGNMENT>& input2,
                    viennacl::vector<SCALARTYPE, ALIGNMENT>& output);

    template <typename T>
    viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<op_prod> >
    element_prod(vector_base<T> const & v1, vector_base<T> const & v2);

    template <typename T>
    viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<op_div> >
    element_div(vector_base<T> const & v1, vector_base<T> const & v2);



    template <typename T>
    void inner_prod_impl(vector_base<T> const & vec1,
                         vector_base<T> const & vec2,
                         scalar<T> & result);

    template <typename LHS, typename RHS, typename OP, typename T>
    void inner_prod_impl(viennacl::vector_expression<LHS, RHS, OP> const & vec1,
                         vector_base<T> const & vec2,
                         scalar<T> & result);

    template <typename T, typename LHS, typename RHS, typename OP>
    void inner_prod_impl(vector_base<T> const & vec1,
                         viennacl::vector_expression<LHS, RHS, OP> const & vec2,
                         scalar<T> & result);

    template <typename LHS1, typename RHS1, typename OP1,
              typename LHS2, typename RHS2, typename OP2, typename T>
    void inner_prod_impl(viennacl::vector_expression<LHS1, RHS1, OP1> const & vec1,
                         viennacl::vector_expression<LHS2, RHS2, OP2> const & vec2,
                         scalar<T> & result);

    ///////////////////////////

    template <typename T>
    void inner_prod_cpu(vector_base<T> const & vec1,
                        vector_base<T> const & vec2,
                        T & result);

    template <typename LHS, typename RHS, typename OP, typename T>
    void inner_prod_cpu(viennacl::vector_expression<LHS, RHS, OP> const & vec1,
                        vector_base<T> const & vec2,
                        T & result);

    template <typename T, typename LHS, typename RHS, typename OP>
    void inner_prod_cpu(vector_base<T> const & vec1,
                        viennacl::vector_expression<LHS, RHS, OP> const & vec2,
                        T & result);

    template <typename LHS1, typename RHS1, typename OP1,
              typename LHS2, typename RHS2, typename OP2, typename S3>
    void inner_prod_cpu(viennacl::vector_expression<LHS1, RHS1, OP1> const & vec1,
                        viennacl::vector_expression<LHS2, RHS2, OP2> const & vec2,
                        S3 & result);



    //forward definition of norm_1_impl function
    template <typename T>
    void norm_1_impl(vector_base<T> const & vec, scalar<T> & result);

    //template <typename T, typename F>
    //void norm_1_impl(matrix_base<T, F> const & A, scalar<T> & result);

    template <typename LHS, typename RHS, typename OP, typename T>
    void norm_1_impl(viennacl::vector_expression<LHS, RHS, OP> const & vec,
                     scalar<T> & result);


    template <typename T>
    void norm_1_cpu(vector_base<T> const & vec,
                    T & result);

    //template <typename T, typename F>
    //void norm_1_cpu(matrix_base<T, F> const & vec,
    //                T & result);

    template <typename LHS, typename RHS, typename OP, typename S2>
    void norm_1_cpu(viennacl::vector_expression<LHS, RHS, OP> const & vec,
                    S2 & result);

    //forward definition of norm_2_impl function
    template <typename T>
    void norm_2_impl(vector_base<T> const & vec, scalar<T> & result);

    template <typename LHS, typename RHS, typename OP, typename T>
    void norm_2_impl(viennacl::vector_expression<LHS, RHS, OP> const & vec,
                     scalar<T> & result);

    template <typename T>
    void norm_2_cpu(vector_base<T> const & vec, T & result);

    template <typename LHS, typename RHS, typename OP, typename S2>
    void norm_2_cpu(viennacl::vector_expression<LHS, RHS, OP> const & vec,
                    S2 & result);


    //forward definition of norm_inf_impl function
    template <typename T>
    void norm_inf_impl(vector_base<T> const & vec, scalar<T> & result);

    //template <typename T, typename F>
    //void norm_inf_impl(matrix_base<T, F> const & vec, scalar<T> & result);

    template <typename LHS, typename RHS, typename OP, typename T>
    void norm_inf_impl(viennacl::vector_expression<LHS, RHS, OP> const & vec,
                      scalar<T> & result);


    template <typename T>
    void norm_inf_cpu(vector_base<T> const & vec, T & result);

    //template <typename T, typename F>
    //void norm_inf_cpu(matrix_base<T, F> const & vec, T & result);

    template <typename LHS, typename RHS, typename OP, typename S2>
    void norm_inf_cpu(viennacl::vector_expression<LHS, RHS, OP> const & vec,
                      S2 & result);

    template <typename T, typename F>
    void norm_frobenius_impl(matrix_base<T, F> const & vec, scalar<T> & result);

    template <typename T, typename F>
    void norm_frobenius_cpu(matrix_base<T, F> const & vec, T & result);


    template <typename T>
    vcl_size_t index_norm_inf(vector_base<T> const & vec);

    template <typename LHS, typename RHS, typename OP>
    vcl_size_t index_norm_inf(viennacl::vector_expression<LHS, RHS, OP> const & vec);

    //forward definition of prod_impl functions

    template <typename NumericT, typename F>
    void prod_impl(const matrix_base<NumericT, F> & mat,
                   const vector_base<NumericT> & vec,
                         vector_base<NumericT> & result);

    template <typename NumericT, typename F>
    void prod_impl(const matrix_expression< const matrix_base<NumericT, F>, const matrix_base<NumericT, F>, op_trans> & mat_trans,
                   const vector_base<NumericT> & vec,
                         vector_base<NumericT> & result);

    template<typename SparseMatrixType, class SCALARTYPE, unsigned int ALIGNMENT>
    typename viennacl::enable_if< viennacl::is_any_sparse_matrix<SparseMatrixType>::value,
                                  vector_expression<const SparseMatrixType,
                                                    const vector<SCALARTYPE, ALIGNMENT>,
                                                    op_prod >
                                 >::type
    prod_impl(const SparseMatrixType & mat,
              const vector<SCALARTYPE, ALIGNMENT> & vec);
#endif

    namespace detail
    {
      enum row_info_types
      {
        SPARSE_ROW_NORM_INF = 0,
        SPARSE_ROW_NORM_1,
        SPARSE_ROW_NORM_2,
        SPARSE_ROW_DIAGONAL
      };

    }


    /** @brief A tag class representing a lower triangular matrix */
    struct lower_tag
    {
      static const char * name() { return "lower"; }
    };      //lower triangular matrix
    /** @brief A tag class representing an upper triangular matrix */
    struct upper_tag
    {
      static const char * name() { return "upper"; }
    };      //upper triangular matrix
    /** @brief A tag class representing a lower triangular matrix with unit diagonal*/
    struct unit_lower_tag
    {
      static const char * name() { return "unit_lower"; }
    }; //unit lower triangular matrix
    /** @brief A tag class representing an upper triangular matrix with unit diagonal*/
    struct unit_upper_tag
    {
      static const char * name() { return "unit_upper"; }
    }; //unit upper triangular matrix

    //preconditioner tags
    class ilut_tag;

    /** @brief A tag class representing the use of no preconditioner */
    class no_precond
    {
      public:
        template <typename VectorType>
        void apply(VectorType &) const {}
    };


  } //namespace linalg

  //
  // More namespace comments to follow:
  //

  /** @brief Namespace providing routines for handling the different memory domains. */
  namespace backend
  {
    /** @brief Provides implementations for handling memory buffers in CPU RAM. */
    namespace cpu_ram
    {
      /** @brief Holds implementation details for handling memory buffers in CPU RAM. Not intended for direct use by library users. */
      namespace detail {}
    }

    /** @brief Provides implementations for handling CUDA memory buffers. */
    namespace cuda
    {
      /** @brief Holds implementation details for handling CUDA memory buffers. Not intended for direct use by library users. */
      namespace detail {}
    }

    /** @brief Implementation details for the generic memory backend interface. */
    namespace detail {}

    /** @brief Provides implementations for handling OpenCL memory buffers. */
    namespace opencl
    {
      /** @brief Holds implementation details for handling OpenCL memory buffers. Not intended for direct use by library users. */
      namespace detail {}
    }
  }


  /** @brief Holds implementation details for functionality in the main viennacl-namespace. Not intended for direct use by library users. */
  namespace detail
  {
    /** @brief Helper namespace for fast Fourier transforms. Not to be used directly by library users. */
    namespace fft
    {
      /** @brief Helper namespace for fast-Fourier transformation. Deprecated. */
      namespace FFT_DATA_ORDER {}
    }
  }


  /** @brief Provides an OpenCL kernel generator. */
  namespace generator
  {
    /** @brief Provides the implementation for tuning the kernels for a particular device. */
    namespace autotune {}

    /** @brief Contains implementation details of the kernel generator. */
    namespace detail {}

    /** @brief Namespace holding the various device-specific parameters for generating the best kernels. */
    namespace profiles {}

    /** @brief Contains various helper routines for kernel generation. */
    namespace utils {}
  }

  /** @brief Provides basic input-output functionality. */
  namespace io
  {
    /** @brief Implementation details for IO functionality. Usually not of interest for a library user. */
    namespace detail {}

    /** @brief Namespace holding the various XML tag definitions for the kernel parameter tuning facility. */
    namespace tag {}

    /** @brief Namespace holding the various XML strings for the kernel parameter tuning facility. */
    namespace val {}
  }

  /** @brief Provides all linear algebra operations which are not covered by operator overloads. */
  namespace linalg
  {
    /** @brief Holds all CUDA compute kernels used by ViennaCL. */
    namespace cuda
    {
      /** @brief Helper functions for the CUDA linear algebra backend. */
      namespace detail {}
    }

    /** @brief Namespace holding implementation details for linear algebra routines. Usually not of interest for a library user. */
    namespace detail
    {
      /** @brief Implementation namespace for algebraic multigrid preconditioner. */
      namespace amg {}

      /** @brief Implementation namespace for sparse approximate inverse preconditioner. */
      namespace spai {}
    }

    /** @brief Holds all compute kernels with conventional host-based execution (buffers in CPU RAM). */
    namespace host_based
    {
      /** @brief Helper functions for the host-based linear algebra backend. */
      namespace detail {}
    }

    /** @brief Namespace containing the OpenCL kernels. Deprecated, will be moved to viennacl::linalg::opencl in future releases. */
    namespace kernels {}

    /** @brief Holds all routines providing OpenCL linear algebra operations. */
    namespace opencl
    {
      /** @brief Helper functions for OpenCL-accelerated linear algebra operations. */
      namespace detail {}

      /** @brief Contains the OpenCL kernel generation functions for a predefined set of functionality. */
      namespace kernels
      {
        /** @brief Implementation details for the predefined OpenCL kernels. */
        namespace detail {}
      }
    }
  }

  /** @brief OpenCL backend. Manages platforms, contexts, buffers, kernels, etc. */
  namespace ocl {}

  /** @brief Namespace containing many meta-functions. */
  namespace result_of {}

  /** @brief Namespace for various tools used within ViennaCL. */
  namespace tools
  {
    /** @brief Contains implementation details for the tools. Usually not of interest for the library user. */
    namespace detail {}
  }

  /** @brief Namespace providing traits-information as well as generic wrappers to common routines for vectors and matrices such as size() or clear() */
  namespace traits {}

  /** @brief Contains the scheduling functionality which allows for dynamic kernel generation as well as the fusion of multiple statements into a single kernel. */
  namespace scheduler
  {
    /** @brief Implementation details for the scheduler */
    namespace detail {}

    /** @brief Helper metafunctions used for the scheduler */
    namespace result_of {}
  }

} //namespace viennacl

#endif

/*@}*/