~kamalmostafa/ubuntu/lucid/pdp/fix-504941-ftbfs

« back to all changes in this revision

Viewing changes to modules/matrix_basic/pdp_mat_mul.c

  • Committer: Bazaar Package Importer
  • Author(s): Guenter Geiger (Debian/GNU)
  • Date: 2005-03-15 22:21:05 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050315222105-1q287rsihmd9j1tb
Tags: 1:0.12.4-2
* fixed the hardcoded depends
* added 3dp library

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *   Pure Data Packet module. Matrix multiplication module
3
 
 *   Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
4
 
 *
5
 
 *   This program is free software; you can redistribute it and/or modify
6
 
 *   it under the terms of the GNU General Public License as published by
7
 
 *   the Free Software Foundation; either version 2 of the License, or
8
 
 *   (at your option) any later version.
9
 
 *
10
 
 *   This program is distributed in the hope that it will be useful,
11
 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *   GNU General Public License for more details.
14
 
 *
15
 
 *   You should have received a copy of the GNU General Public License
16
 
 *   along with this program; if not, write to the Free Software
17
 
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
 
 *
19
 
 */
20
 
 
21
 
//#include <gsl/gsl_block.h>
22
 
//#include <gsl/gsl_vector.h>
23
 
//#include <gsl/gsl_matrix.h>
24
 
//#include <gsl/gsl_blas.h>
25
 
#include "pdp.h"
26
 
#include "pdp_base.h"
27
 
 
28
 
 
29
 
typedef struct pdp_mat_mm_struct
30
 
{
31
 
    t_pdp_base x_base;
32
 
    CBLAS_TRANSPOSE_t x_T0;
33
 
    CBLAS_TRANSPOSE_t x_T1;
34
 
    int x_M0;
35
 
    int x_M1;
36
 
 
37
 
    float x_scale_r;
38
 
    float x_scale_i;
39
 
 
40
 
} t_pdp_mat_mm;
41
 
 
42
 
 
43
 
static void pdp_mat_mm_rscale(t_pdp_mat_mm *x, t_floatarg r)
44
 
{
45
 
    x->x_scale_r = r;
46
 
    x->x_scale_i = 0.0f;
47
 
}
48
 
 
49
 
static void pdp_mat_mm_cscale(t_pdp_mat_mm *x, t_floatarg r, t_floatarg i)
50
 
{
51
 
    x->x_scale_r = r;
52
 
    x->x_scale_i = i;
53
 
}
54
 
 
55
 
 
56
 
/* matrix multilpy */
57
 
static void pdp_mat_mv_process_mul(t_pdp_mat_mm *x)
58
 
{
59
 
    int pA = pdp_base_get_packet(x, 0);
60
 
    int pB = pdp_base_get_packet(x, 1);
61
 
    int p0, p1, pR;
62
 
 
63
 
    /* determine which one is the vector */
64
 
    if (pdp_packet_matrix_isvector(pA)){
65
 
        p0 = pB;
66
 
        p1 = pA;
67
 
    }
68
 
    else {
69
 
        p1 = pB;
70
 
        p0 = pA;
71
 
    }
72
 
 
73
 
    pR = pdp_packet_new_matrix_product_result(x->x_T0, CblasNoTrans, p0, p1);
74
 
 
75
 
    if (-1 != pR){
76
 
        pdp_packet_matrix_setzero(pR);
77
 
        if (pdp_packet_matrix_blas_mv(x->x_T0, p0, p1, pR, x->x_scale_r, x->x_scale_i)){
78
 
            //post("pdp_packet_matrix_blas_mm failed");
79
 
            pdp_packet_mark_unused(pR);
80
 
            pR = -1;
81
 
        }
82
 
    }
83
 
    else {
84
 
        //post("pdp_packet_new_matrix_product_result failed");
85
 
    }
86
 
 
87
 
    /* replace with result */
88
 
    pdp_base_set_packet(x, 0, pR);
89
 
 
90
 
}
91
 
 
92
 
/* matrix vector multilpy */
93
 
static void pdp_mat_mm_process_mul(t_pdp_mat_mm *x)
94
 
{
95
 
    int pA = pdp_base_get_packet(x, 0);
96
 
    int pB = pdp_base_get_packet(x, 1);
97
 
    int p0, p1, pR;
98
 
 
99
 
    p0 = (x->x_M0) ? pB : pA;
100
 
    p1 = (x->x_M1) ? pB : pA;
101
 
 
102
 
    pR = pdp_packet_new_matrix_product_result(x->x_T0, x->x_T1, p0, p1);
103
 
 
104
 
    if (-1 != pR){
105
 
        pdp_packet_matrix_setzero(pR);
106
 
        if (pdp_packet_matrix_blas_mm(x->x_T0, x->x_T1, p0, p1, pR, x->x_scale_r, x->x_scale_i)){
107
 
            //post("pdp_packet_matrix_blas_mm failed");
108
 
            pdp_packet_mark_unused(pR);
109
 
            pR = -1;
110
 
        }
111
 
    }
112
 
    else {
113
 
        //post("pdp_packet_new_matrix_product_result failed");
114
 
    }
115
 
 
116
 
    /* replace with result */
117
 
    pdp_base_set_packet(x, 0, pR);
118
 
 
119
 
}
120
 
/* matrix macc */
121
 
static void pdp_mat_mm_process_mac(t_pdp_mat_mm *x)
122
 
{
123
 
    int pC = pdp_base_get_packet(x, 0);
124
 
    int pA = pdp_base_get_packet(x, 1);
125
 
    int pB = pdp_base_get_packet(x, 2);
126
 
    int p0, p1;
127
 
 
128
 
    p0 = (x->x_M0) ? pB : pA;
129
 
    p1 = (x->x_M1) ? pB : pA;
130
 
 
131
 
    if (pdp_packet_matrix_blas_mm(x->x_T0, x->x_T1, p0, p1, pC, x->x_scale_r, x->x_scale_i)){
132
 
        //post("pdp_packet_matrix_blas_mm failed");
133
 
        pdp_base_set_packet(x, 0, -1); // delete packet
134
 
    }
135
 
 
136
 
}
137
 
 
138
 
 
139
 
static void pdp_mat_mm_free(t_pdp_mat_mm *x)
140
 
{
141
 
    /* remove process method from queue before deleting data */
142
 
    pdp_base_free(x);
143
 
}
144
 
 
145
 
t_class *pdp_mat_mm_class;
146
 
 
147
 
 
148
 
/* common new method */
149
 
void *pdp_mat_mm_new(void)
150
 
{
151
 
    int i;
152
 
    t_pdp_mat_mm *x = (t_pdp_mat_mm *)pd_new(pdp_mat_mm_class);
153
 
 
154
 
    /* super init */
155
 
    pdp_base_init(x);
156
 
 
157
 
    /* outlet */
158
 
    pdp_base_add_pdp_outlet(x);
159
 
 
160
 
 
161
 
    return (void *)x;
162
 
}
163
 
 
164
 
 
165
 
static int pdp_mat_mm_setup_routing_M0(t_pdp_mat_mm *x, t_symbol *s0)
166
 
{
167
 
     if ('A' == s0->s_name[0]){x->x_M0 = 0;} else if ('B' == s0->s_name[0]) {x->x_M0 = 1;} else return 0;
168
 
 
169
 
     if ((gensym("A") == s0) || (gensym("B") == s0)) x->x_T0 = CblasNoTrans;
170
 
     else if ((gensym("A^T") == s0) || (gensym("B^T") == s0)) x->x_T0 = CblasConjTrans;
171
 
     else if ((gensym("A^H") == s0) || (gensym("B^H") == s0)) x->x_T0 = CblasConjTrans;
172
 
     else return 0;
173
 
 
174
 
     return 1;
175
 
}
176
 
 
177
 
static int pdp_mat_mm_setup_routing_M1(t_pdp_mat_mm *x, t_symbol *s1)
178
 
{
179
 
 
180
 
     if ('A' == s1->s_name[0]){x->x_M1 = 0;} else if ('B' == s1->s_name[0]) {x->x_M1 = 1;} else return 0;
181
 
 
182
 
     /* setup second matrix transpose operation */
183
 
     if ((gensym("A") == s1) || (gensym("B") == s1)) x->x_T1 = CblasNoTrans;
184
 
     else if ((gensym("A^T") == s1) || (gensym("B^T") == s1)) x->x_T1 = CblasConjTrans;
185
 
     else if ((gensym("A^H") == s1) || (gensym("B^H") == s1)) x->x_T1 = CblasConjTrans;
186
 
     else return 0;
187
 
 
188
 
     return 1;
189
 
}
190
 
 
191
 
 
192
 
static int pdp_mat_mm_setup_scaling(t_pdp_mat_mm *x, t_symbol *scale)
193
 
{
194
 
    int success = 1;
195
 
 
196
 
     /* setup scaling inlet */
197
 
     if ((gensym ("rscale") == scale) || (gensym("r") == scale)){
198
 
         pdp_base_add_gen_inlet(x, gensym("float"), gensym("rscale"));
199
 
     }
200
 
     else if ((gensym ("cscale") == scale) || (gensym("c") == scale)){
201
 
         pdp_base_add_gen_inlet(x, gensym("list"), gensym("cscale"));
202
 
     }
203
 
     else if (gensym ("") != scale) success = 0;
204
 
     
205
 
     return success;
206
 
}
207
 
 
208
 
void *pdp_mat_mm_new_mul_common(t_symbol *s0, t_symbol *s1, t_symbol *scale, int ein)
209
 
{
210
 
     t_pdp_mat_mm *x = pdp_mat_mm_new();
211
 
 
212
 
     /* add extra pdp inlets */
213
 
     while (ein--) pdp_base_add_pdp_inlet(x);
214
 
 
215
 
     /* setup routing */
216
 
     if (!pdp_mat_mm_setup_routing_M0(x, s0)) goto error;
217
 
     if (!pdp_mat_mm_setup_routing_M1(x, s1)) goto error;
218
 
     if (!pdp_mat_mm_setup_scaling(x, scale)) goto error;
219
 
 
220
 
     /* default scale = 1 */
221
 
     pdp_mat_mm_cscale(x, 1.0f, 0.0f);
222
 
     return (void *)x;
223
 
 
224
 
 error:
225
 
     pd_free((void *)x);
226
 
     return 0;
227
 
}
228
 
 
229
 
void *pdp_mat_mv_new_mul_common(t_symbol *s0, t_symbol *scale, int ein)
230
 
{
231
 
     t_pdp_mat_mm *x = pdp_mat_mm_new();
232
 
 
233
 
     /* add extra pdp inlets */
234
 
     while (ein--) pdp_base_add_pdp_inlet(x);
235
 
 
236
 
     /* setup routing */
237
 
     if (!pdp_mat_mm_setup_routing_M0(x, s0)) goto error;
238
 
     if (!pdp_mat_mm_setup_scaling(x, scale)) goto error;
239
 
 
240
 
     /* default scale = 1 */
241
 
     pdp_mat_mm_cscale(x, 1.0f, 0.0f);
242
 
     return (void *)x;
243
 
 
244
 
 error:
245
 
     pd_free((void *)x);
246
 
     return 0;
247
 
}
248
 
 
249
 
void *pdp_mat_mm_new_mul(t_symbol *s0, t_symbol *s1, t_symbol *scale)
250
 
{
251
 
    t_pdp_mat_mm *x = pdp_mat_mm_new_mul_common(s0, s1, scale, 1);
252
 
    if(x){
253
 
        pdp_base_set_process_method(x, (t_pdp_method)pdp_mat_mm_process_mul);
254
 
        pdp_base_readonly_active_inlet(x);
255
 
    }
256
 
    return x;
257
 
}
258
 
 
259
 
void *pdp_mat_mv_new_mul(t_symbol *s0, t_symbol *scale)
260
 
{
261
 
    t_pdp_mat_mm *x = pdp_mat_mv_new_mul_common(s0, scale, 1);
262
 
    if(x){
263
 
        pdp_base_set_process_method(x, (t_pdp_method)pdp_mat_mv_process_mul);
264
 
        pdp_base_readonly_active_inlet(x);
265
 
    }
266
 
    return x;
267
 
}
268
 
 
269
 
void *pdp_mat_mm_new_mac(t_symbol *s0, t_symbol *s1, t_symbol *scale)
270
 
{
271
 
    t_pdp_mat_mm *x = pdp_mat_mm_new_mul_common(s0, s1, scale, 2);
272
 
    if (x){
273
 
        pdp_base_set_process_method(x, (t_pdp_method)pdp_mat_mm_process_mac);
274
 
    }
275
 
    return x;
276
 
}
277
 
 
278
 
 
279
 
#ifdef __cplusplus
280
 
extern "C"
281
 
{
282
 
#endif
283
 
 
284
 
 
285
 
void pdp_mat_mul_setup(void)
286
 
{
287
 
 
288
 
 
289
 
    pdp_mat_mm_class = class_new(gensym("pdp_m_mm"), (t_newmethod)pdp_mat_mm_new_mul,
290
 
        (t_method)pdp_mat_mm_free, sizeof(t_pdp_mat_mm), 0, A_SYMBOL, A_SYMBOL, A_DEFSYMBOL, A_NULL);
291
 
 
292
 
    pdp_base_setup(pdp_mat_mm_class);
293
 
 
294
 
    class_addcreator((t_newmethod)pdp_mat_mm_new_mac, gensym("pdp_m_+=mm"),
295
 
                     A_SYMBOL, A_SYMBOL, A_DEFSYMBOL, A_NULL);
296
 
  
297
 
    class_addcreator((t_newmethod)pdp_mat_mv_new_mul, gensym("pdp_m_mv"),
298
 
                     A_SYMBOL, A_DEFSYMBOL, A_NULL);
299
 
  
300
 
 
301
 
    class_addmethod(pdp_mat_mm_class, (t_method)pdp_mat_mm_rscale, gensym("rscale"), A_FLOAT, A_NULL);
302
 
    class_addmethod(pdp_mat_mm_class, (t_method)pdp_mat_mm_cscale, gensym("cscale"), A_FLOAT, A_FLOAT, A_NULL);
303
 
 
304
 
}
305
 
 
306
 
#ifdef __cplusplus
307
 
}
308
 
#endif