Skip to content

Commit

Permalink
several bug fixes to make a non-trivial example work. GEMM calls were…
Browse files Browse the repository at this point in the history
…n't respecting lazy transposes, so force that to happen in several places. Also both Gemm methods were returning the wrong value and not respecting forced conversions on parameter C
  • Loading branch information
Whiteknight committed Aug 20, 2010
1 parent c843c5e commit c171c07
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 30 deletions.
53 changes: 45 additions & 8 deletions src/pmc/complexmatrix2d.pmc
Expand Up @@ -36,11 +36,44 @@ get_complex_value_from_pmc(PARROT_INTERP, PMC * value, FLOATVAL * real, FLOATVAL
}
}

/* If the matrix is lazily transposed, actually transpose the physical memory
layout. This is necessary for calculations, especially BLAS calculations,
which aren't lazy-transpose-aware. */
static void
normalize_lazy_transpose(PARROT_INTERP, PMC * self)
{
DECLATTRS(self, attrs);
if (IS_TRANSPOSED(attrs->flags)) {
const INTVAL rows_size = attrs->rows;
const INTVAL cols_size = attrs->cols;
const INTVAL size = rows_size * cols_size;
FLOATVAL * const new_s = ALLOCATE_STORAGE(size);
FLOATVAL * const old_s = attrs->storage;
INTVAL i, j;

for (i = 0; i < rows_size; ++i) {
for (j = 0; j < cols_size; ++j) {
R_ITEM_XY_COLMAJOR(new_s, rows_size, cols_size, i, j) =
R_ITEM_XY_ROWMAJOR(old_s, rows_size, cols_size, i, j);
I_ITEM_XY_COLMAJOR(new_s, rows_size, cols_size, i, j) =
I_ITEM_XY_ROWMAJOR(old_s, rows_size, cols_size, i, j);
}
}
attrs->storage = new_s;
mem_sys_free(old_s);
FLAG_CLEAR(attrs->flags, FLAG_TRANSPOSED);
}
}

static PMC *
convert_to_ComplexMatrix2D(PARROT_INTERP, PMC * p)
convert_to_ComplexMatrix2D(PARROT_INTERP, PMC * p, INTVAL forcecopy)
{
if (p->vtable->base_type == __PLA_Type_ComplexMatrix2D)
if (p->vtable->base_type == __PLA_Type_ComplexMatrix2D) {
normalize_lazy_transpose(interp, p);
if (forcecopy)
return VTABLE_clone(interp, p);
return p;
}
else if (!VTABLE_does(interp, p, CONST_STRING(interp, "matrix")))
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
PLATYPENAME ": cannot convert unknown PMC type");
Expand All @@ -52,6 +85,7 @@ convert_to_ComplexMatrix2D(PARROT_INTERP, PMC * p)
}
}


/* Resize the matrix internal storage to be able to hold a point at position
(x, y). The matrix grows but does not shrink. New spaces in the matrix
are initialized to 0.0. Parameters x and y are the indices that are trying
Expand Down Expand Up @@ -198,6 +232,7 @@ call_gemm(PARROT_INTERP, FLOATVAL alpha_r, FLOATVAL alpha_i, PMC * A, PMC *B,
alpha_p[1] = alpha_i;
beta_p[0] = beta_r;
beta_p[1] = beta_i;
fprintf(stderr, "%f %f %f %f\n", alpha_r, alpha_i, beta_r, beta_i);
cblas_zgemm(CblasRowMajor,
IS_TRANSPOSED_BLAS(attrs_a->flags),
IS_TRANSPOSED_BLAS(attrs_b->flags),
Expand Down Expand Up @@ -1321,15 +1356,14 @@ Calculates the matrix equation:
*/

METHOD gemm(PMC *alpha, PMC * A, PMC *B, PMC *beta, PMC *C) {
PMC * const c_out = VTABLE_clone(INTERP, C);
FLOATVAL alpha_r, alpha_i, beta_r, beta_i;
A = convert_to_ComplexMatrix2D(interp, A);
B = convert_to_ComplexMatrix2D(interp, B);
C = convert_to_ComplexMatrix2D(interp, C);
A = convert_to_ComplexMatrix2D(interp, A, 0);
B = convert_to_ComplexMatrix2D(interp, B, 0);
C = convert_to_ComplexMatrix2D(interp, C, 1);
get_complex_value_from_pmc(interp, alpha, &alpha_r, &alpha_i);
get_complex_value_from_pmc(interp, beta, &beta_r, &beta_i);
call_gemm(INTERP, alpha_r, alpha_i, A, B, beta_r, beta_i, c_out);
RETURN(PMC* c_out);
call_gemm(INTERP, alpha_r, alpha_i, A, B, beta_r, beta_i, C);
RETURN(PMC* C);
}

/*
Expand Down Expand Up @@ -1431,6 +1465,7 @@ Get a PMCMatrix2D from the current matrix
PMC * const meth = VTABLE_find_method(INTERP, d, CONST_STRING(INTERP, "resize"));
INTVAL i;
Parrot_ext_call(INTERP, meth, "PiII->", d, attrs->rows, attrs->cols);
normalize_lazy_transpose(INTERP, SELF);
for (i = 0; i < totalsize; i++) {
const FLOATVAL f = VTABLE_get_number_keyed_int(INTERP, SELF, i);
VTABLE_set_number_keyed_int(INTERP, d, i, f);
Expand All @@ -1440,6 +1475,7 @@ Get a PMCMatrix2D from the current matrix

METHOD convert_to_complex_matrix() {
PMC * const d = VTABLE_clone(INTERP, SELF);
normalize_lazy_transpose(INTERP, d);
RETURN(PMC * d);
}

Expand All @@ -1450,6 +1486,7 @@ Get a PMCMatrix2D from the current matrix
PMC * const meth = VTABLE_find_method(INTERP, d, CONST_STRING(INTERP, "resize"));
INTVAL i;
Parrot_ext_call(INTERP, meth, "PiII->", d, attrs->rows, attrs->cols);
normalize_lazy_transpose(INTERP, SELF);
for (i = 0; i < totalsize; i++) {
PMC * const p = VTABLE_get_pmc_keyed_int(INTERP, SELF, i);
VTABLE_set_pmc_keyed_int(INTERP, d, i, p);
Expand Down
50 changes: 28 additions & 22 deletions src/pmc/nummatrix2d.pmc
Expand Up @@ -18,22 +18,6 @@

INTVAL __PLA_Type_NumMatrix2D;

static PMC *
convert_to_NumMatrix2D(PARROT_INTERP, PMC * p)
{
if (p->vtable->base_type == __PLA_Type_NumMatrix2D)
return p;
else if (!VTABLE_does(interp, p, CONST_STRING(interp, "matrix")))
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
PLATYPENAME ": cannot convert unknown PMC type");
else {
PMC * const meth = VTABLE_find_method(interp, p, CONST_STRING(interp, "convert_to_number_matrix"));
PMC * dest = PMCNULL;
Parrot_ext_call(interp, meth, "Pi->P", p, &dest);
return dest;
}
}

/* Resize the matrix internal storage to be able to hold a point at position
(x, y). The matrix grows but does not shrink. New spaces in the matrix
are initialized to 0.0. Parameters x and y are the indices that are trying
Expand Down Expand Up @@ -102,6 +86,26 @@ normalize_lazy_transpose(PARROT_INTERP, PMC * self)
}
}

static PMC *
convert_to_NumMatrix2D(PARROT_INTERP, PMC * p, INTVAL forcecopy)
{
if (p->vtable->base_type == __PLA_Type_NumMatrix2D) {
normalize_lazy_transpose(interp, p);
if (forcecopy)
return VTABLE_clone(interp, p);
return p;
}
else if (!VTABLE_does(interp, p, CONST_STRING(interp, "matrix")))
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
PLATYPENAME ": cannot convert unknown PMC type");
else {
PMC * const meth = VTABLE_find_method(interp, p, CONST_STRING(interp, "convert_to_number_matrix"));
PMC * dest = PMCNULL;
Parrot_ext_call(interp, meth, "Pi->P", p, &dest);
return dest;
}
}

/* Initialize the PMC from an array, filling the matrix row-at-a-time */
static void
init_from_pmc_array(PARROT_INTERP, PMC * self, INTVAL rows_size,
Expand Down Expand Up @@ -1221,12 +1225,11 @@ Calculates the matrix equation:
*/

METHOD gemm(FLOATVAL alpha, PMC * A, PMC *B, FLOATVAL beta, PMC *C) {
PMC * const c_out = VTABLE_clone(INTERP, C);
A = convert_to_NumMatrix2D(interp, A);
B = convert_to_NumMatrix2D(interp, B);
C = convert_to_NumMatrix2D(interp, C);
call_gemm(INTERP, alpha, A, B, beta, c_out);
RETURN(PMC* c_out);
A = convert_to_NumMatrix2D(interp, A, 0);
B = convert_to_NumMatrix2D(interp, B, 0);
C = convert_to_NumMatrix2D(interp, C, 1);
call_gemm(INTERP, alpha, A, B, beta, C);
RETURN(PMC* C);
}

/*
Expand Down Expand Up @@ -1317,6 +1320,7 @@ Get a PMCMatrix2D from the current matrix

METHOD convert_to_number_matrix() {
PMC * const d = VTABLE_clone(INTERP, SELF);
normalize_lazy_transpose(INTERP, d);
RETURN(PMC * d);
}

Expand All @@ -1327,6 +1331,7 @@ Get a PMCMatrix2D from the current matrix
PMC * const meth = VTABLE_find_method(INTERP, d, CONST_STRING(INTERP, "resize"));
INTVAL i;
Parrot_ext_call(INTERP, meth, "PiII->", d, attrs->rows, attrs->cols);
normalize_lazy_transpose(INTERP, SELF);
for (i = 0; i < totalsize; i++) {
const FLOATVAL f = VTABLE_get_number_keyed_int(INTERP, SELF, i);
VTABLE_set_number_keyed_int(INTERP, d, i, f);
Expand All @@ -1341,6 +1346,7 @@ Get a PMCMatrix2D from the current matrix
PMC * const meth = VTABLE_find_method(INTERP, d, CONST_STRING(INTERP, "resize"));
INTVAL i;
Parrot_ext_call(INTERP, meth, "PiII->", d, attrs->rows, attrs->cols);
normalize_lazy_transpose(INTERP, SELF);
for (i = 0; i < totalsize; i++) {
const FLOATVAL f = VTABLE_get_number_keyed_int(INTERP, SELF, i);
VTABLE_set_number_keyed_int(INTERP, d, i, f);
Expand Down
30 changes: 30 additions & 0 deletions src/pmc/pmcmatrix2d.pmc
Expand Up @@ -80,6 +80,33 @@ init_from_pmc_array(PARROT_INTERP, PMC * self, INTVAL rows_size, INTVAL cols_siz
}
}

/* If the matrix is lazily transposed, actually transpose the physical memory
layout. This is necessary for calculations, especially BLAS calculations,
which aren't lazy-transpose-aware. */
static void
normalize_lazy_transpose(PARROT_INTERP, PMC * self)
{
DECLATTRS(self, attrs);
if (IS_TRANSPOSED(attrs->flags)) {
const INTVAL rows_size = attrs->rows;
const INTVAL cols_size = attrs->cols;
const INTVAL size = rows_size * cols_size;
FLOATVAL * const new_s = ALLOCATE_STORAGE(size);
FLOATVAL * const old_s = attrs->storage;
INTVAL i, j;

for (i = 0; i < rows_size; ++i) {
for (j = 0; j < cols_size; ++j) {
ITEM_XY_COLMAJOR(new_s, rows_size, cols_size, i, j) =
ITEM_XY_ROWMAJOR(old_s, rows_size, cols_size, i, j);
}
}
attrs->storage = new_s;
mem_sys_free(old_s);
FLAG_CLEAR(attrs->flags, FLAG_TRANSPOSED);
}
}


pmclass PMCMatrix2D dynpmc auto_attrs provides matrix {
ATTR PMC ** storage;
Expand Down Expand Up @@ -699,6 +726,7 @@ Get a PMCMatrix2D from the current matrix
PMC * const meth = VTABLE_find_method(INTERP, d, CONST_STRING(INTERP, "resize"));
INTVAL i;
Parrot_ext_call(INTERP, meth, "PiII->", d, attrs->rows, attrs->cols);
normalize_lazy_transpose(INTERP, SELF);
for (i = 0; i < totalsize; i++) {
const FLOATVAL f = VTABLE_get_number_keyed_int(INTERP, SELF, i);
VTABLE_set_number_keyed_int(INTERP, d, i, f);
Expand All @@ -713,6 +741,7 @@ Get a PMCMatrix2D from the current matrix
PMC * const meth = VTABLE_find_method(INTERP, d, CONST_STRING(INTERP, "resize"));
INTVAL i;
Parrot_ext_call(INTERP, meth, "PiII->", d, attrs->rows, attrs->cols);
normalize_lazy_transpose(INTERP, SELF);
for (i = 0; i < totalsize; i++) {
PMC * const p = VTABLE_get_pmc_keyed_int(INTERP, SELF, i);
VTABLE_set_pmc_keyed_int(INTERP, d, i, p);
Expand All @@ -722,6 +751,7 @@ Get a PMCMatrix2D from the current matrix

METHOD convert_to_pmc_matrix() {
PMC * const d = VTABLE_clone(INTERP, SELF);
normalize_lazy_transpose(INTERP, d);
RETURN(PMC * d);
}

Expand Down

0 comments on commit c171c07

Please sign in to comment.