2578 |
return o; |
return o; |
2579 |
} |
} |
2580 |
|
|
2581 |
|
Data |
2582 |
|
escript::C_GeneralTensorProduct(Data& arg_0, |
2583 |
|
Data& arg_1, |
2584 |
|
int axis_offset, |
2585 |
|
int transpose) |
2586 |
|
{ |
2587 |
|
// General tensor product: arg_2(SL x SR) = arg_0(SL x SM) * arg_1(SM x SR) |
2588 |
|
// SM is the product of the last axis_offset entries in arg_0.getShape(). |
2589 |
|
|
2590 |
|
#if defined DOPROF |
2591 |
|
// profData->binary++; |
2592 |
|
#endif |
2593 |
|
|
2594 |
|
// Interpolate if necessary and find an appropriate function space |
2595 |
|
if (arg_0.getFunctionSpace()!=arg_1.getFunctionSpace()) { |
2596 |
|
if (arg_0.probeInterpolation(arg_1.getFunctionSpace())) { |
2597 |
|
Data arg_0_tmp = arg_0.interpolate(arg_1.getFunctionSpace()); |
2598 |
|
arg_1=arg_0_tmp; |
2599 |
|
} |
2600 |
|
else if (arg_1.probeInterpolation(arg_0.getFunctionSpace())) { |
2601 |
|
arg_1=arg_1.interpolate(arg_0.getFunctionSpace()); |
2602 |
|
} |
2603 |
|
else { |
2604 |
|
throw DataException("Error - C_GeneralTensorProduct: arguments have incompatible function spaces."); |
2605 |
|
} |
2606 |
|
} |
2607 |
|
|
2608 |
|
// Get rank and shape of inputs |
2609 |
|
int rank0 = arg_0.getDataPointRank(); |
2610 |
|
int rank1 = arg_1.getDataPointRank(); |
2611 |
|
DataArrayView::ShapeType shape0 = arg_0.getDataPointShape(); |
2612 |
|
DataArrayView::ShapeType shape1 = arg_1.getDataPointShape(); |
2613 |
|
|
2614 |
|
// Prepare for the loops of the product and verify compatibility of shapes |
2615 |
|
int start0=0, start1=0; |
2616 |
|
if (transpose == 0) {} |
2617 |
|
else if (transpose == 1) { start0 = axis_offset; } |
2618 |
|
else if (transpose == 2) { start1 = rank1-axis_offset; } |
2619 |
|
else { throw DataException("C_GeneralTensorProduct: Error - transpose should be 0, 1 or 2"); } |
2620 |
|
|
2621 |
|
// Adjust the shapes for transpose |
2622 |
|
DataArrayView::ShapeType tmpShape0; |
2623 |
|
DataArrayView::ShapeType tmpShape1; |
2624 |
|
for (int i=0; i<rank0; i++) { tmpShape0.push_back( shape0[(i+start0)%rank0] ); } |
2625 |
|
for (int i=0; i<rank1; i++) { tmpShape1.push_back( shape1[(i+start1)%rank1] ); } |
2626 |
|
|
2627 |
|
#if 0 |
2628 |
|
// For debugging: show shape after transpose |
2629 |
|
char tmp[100]; |
2630 |
|
std::string shapeStr; |
2631 |
|
shapeStr = "("; |
2632 |
|
for (int i=0; i<rank0; i++) { sprintf(tmp, "%d,", tmpShape0[i]); shapeStr += tmp; } |
2633 |
|
shapeStr += ")"; |
2634 |
|
cout << "C_GeneralTensorProduct: Shape of arg0 is " << shapeStr << endl; |
2635 |
|
shapeStr = "("; |
2636 |
|
for (int i=0; i<rank1; i++) { sprintf(tmp, "%d,", tmpShape1[i]); shapeStr += tmp; } |
2637 |
|
shapeStr += ")"; |
2638 |
|
cout << "C_GeneralTensorProduct: Shape of arg1 is " << shapeStr << endl; |
2639 |
|
#endif |
2640 |
|
|
2641 |
|
// Prepare for the loops of the product |
2642 |
|
int SL=1, SM=1, SR=1; |
2643 |
|
for (int i=0; i<rank0-axis_offset; i++) { |
2644 |
|
SL *= tmpShape0[i]; |
2645 |
|
} |
2646 |
|
for (int i=rank0-axis_offset; i<rank0; i++) { |
2647 |
|
if (tmpShape0[i] != tmpShape1[i-(rank0-axis_offset)]) { |
2648 |
|
throw DataException("C_GeneralTensorProduct: Error - incompatible shapes"); |
2649 |
|
} |
2650 |
|
SM *= tmpShape0[i]; |
2651 |
|
} |
2652 |
|
for (int i=axis_offset; i<rank1; i++) { |
2653 |
|
SR *= tmpShape1[i]; |
2654 |
|
} |
2655 |
|
|
2656 |
|
// Define the shape of the output |
2657 |
|
DataArrayView::ShapeType shape2; |
2658 |
|
for (int i=0; i<rank0-axis_offset; i++) { shape2.push_back(tmpShape0[i]); } // First part of arg_0 |
2659 |
|
for (int i=axis_offset; i<rank1; i++) { shape2.push_back(tmpShape1[i]); } // Last part of arg_1 |
2660 |
|
|
2661 |
|
// Declare output Data object |
2662 |
|
Data arg_2; |
2663 |
|
|
2664 |
|
if (arg_0.isConstant() && arg_1.isConstant()) { |
2665 |
|
arg_2 = Data(0.0, shape2, arg_1.getFunctionSpace()); // DataConstant output |
2666 |
|
double *ptr_0 = &((arg_0.getPointDataView().getData())[0]); |
2667 |
|
double *ptr_1 = &((arg_1.getPointDataView().getData())[0]); |
2668 |
|
double *ptr_2 = &((arg_2.getPointDataView().getData())[0]); |
2669 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2670 |
|
} |
2671 |
|
else if (arg_0.isConstant() && arg_1.isTagged()) { |
2672 |
|
|
2673 |
|
// Prepare the DataConstant input |
2674 |
|
DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0.borrowData()); |
2675 |
|
if (tmp_0==0) { throw DataException("GTP Programming error - casting to DataConstant."); } |
2676 |
|
|
2677 |
|
// Borrow DataTagged input from Data object |
2678 |
|
DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1.borrowData()); |
2679 |
|
if (tmp_1==0) { throw DataException("GTP_1 Programming error - casting to DataTagged."); } |
2680 |
|
|
2681 |
|
// Prepare a DataTagged output 2 |
2682 |
|
arg_2 = Data(0.0, shape2, arg_1.getFunctionSpace()); // DataTagged output |
2683 |
|
arg_2.tag(); |
2684 |
|
DataTagged* tmp_2=dynamic_cast<DataTagged*>(arg_2.borrowData()); |
2685 |
|
if (tmp_2==0) { throw DataException("GTP Programming error - casting to DataTagged."); } |
2686 |
|
|
2687 |
|
// Prepare offset into DataConstant |
2688 |
|
int offset_0 = tmp_0->getPointOffset(0,0); |
2689 |
|
double *ptr_0 = &((arg_0.getPointDataView().getData())[offset_0]); |
2690 |
|
// Get the views |
2691 |
|
DataArrayView view_1 = tmp_1->getDefaultValue(); |
2692 |
|
DataArrayView view_2 = tmp_2->getDefaultValue(); |
2693 |
|
// Get the pointers to the actual data |
2694 |
|
double *ptr_1 = &((view_1.getData())[0]); |
2695 |
|
double *ptr_2 = &((view_2.getData())[0]); |
2696 |
|
// Compute an MVP for the default |
2697 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2698 |
|
// Compute an MVP for each tag |
2699 |
|
const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup(); |
2700 |
|
DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory |
2701 |
|
for (i=lookup_1.begin();i!=lookup_1.end();i++) { |
2702 |
|
tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); |
2703 |
|
DataArrayView view_1 = tmp_1->getDataPointByTag(i->first); |
2704 |
|
DataArrayView view_2 = tmp_2->getDataPointByTag(i->first); |
2705 |
|
double *ptr_1 = &view_1.getData(0); |
2706 |
|
double *ptr_2 = &view_2.getData(0); |
2707 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2708 |
|
} |
2709 |
|
|
2710 |
|
} |
2711 |
|
else if (arg_0.isConstant() && arg_1.isExpanded()) { |
2712 |
|
|
2713 |
|
arg_2 = Data(0.0, shape2, arg_1.getFunctionSpace(),true); // DataExpanded output |
2714 |
|
DataConstant* tmp_0=dynamic_cast<DataConstant*>(arg_0.borrowData()); |
2715 |
|
DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1.borrowData()); |
2716 |
|
DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(arg_2.borrowData()); |
2717 |
|
if (tmp_0==0) { throw DataException("GTP Programming error - casting to DataConstant."); } |
2718 |
|
if (tmp_1==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2719 |
|
if (tmp_2==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2720 |
|
int sampleNo_1,dataPointNo_1; |
2721 |
|
int numSamples_1 = arg_1.getNumSamples(); |
2722 |
|
int numDataPointsPerSample_1 = arg_1.getNumDataPointsPerSample(); |
2723 |
|
int offset_0 = tmp_0->getPointOffset(0,0); |
2724 |
|
#pragma omp parallel for private(sampleNo_1,dataPointNo_1) schedule(static) |
2725 |
|
for (sampleNo_1 = 0; sampleNo_1 < numSamples_1; sampleNo_1++) { |
2726 |
|
for (dataPointNo_1 = 0; dataPointNo_1 < numDataPointsPerSample_1; dataPointNo_1++) { |
2727 |
|
int offset_1 = tmp_1->getPointOffset(sampleNo_1,dataPointNo_1); |
2728 |
|
int offset_2 = tmp_2->getPointOffset(sampleNo_1,dataPointNo_1); |
2729 |
|
double *ptr_0 = &((arg_0.getPointDataView().getData())[offset_0]); |
2730 |
|
double *ptr_1 = &((arg_1.getPointDataView().getData())[offset_1]); |
2731 |
|
double *ptr_2 = &((arg_2.getPointDataView().getData())[offset_2]); |
2732 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2733 |
|
} |
2734 |
|
} |
2735 |
|
|
2736 |
|
} |
2737 |
|
else if (arg_0.isTagged() && arg_1.isConstant()) { |
2738 |
|
|
2739 |
|
// Borrow DataTagged input from Data object |
2740 |
|
DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0.borrowData()); |
2741 |
|
if (tmp_0==0) { throw DataException("GTP_0 Programming error - casting to DataTagged."); } |
2742 |
|
|
2743 |
|
// Prepare the DataConstant input |
2744 |
|
DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1.borrowData()); |
2745 |
|
if (tmp_1==0) { throw DataException("GTP Programming error - casting to DataConstant."); } |
2746 |
|
|
2747 |
|
// Prepare a DataTagged output 2 |
2748 |
|
arg_2 = Data(0.0, shape2, arg_0.getFunctionSpace()); // DataTagged output |
2749 |
|
arg_2.tag(); |
2750 |
|
DataTagged* tmp_2=dynamic_cast<DataTagged*>(arg_2.borrowData()); |
2751 |
|
if (tmp_2==0) { throw DataException("GTP Programming error - casting to DataTagged."); } |
2752 |
|
|
2753 |
|
// Prepare offset into DataConstant |
2754 |
|
int offset_1 = tmp_1->getPointOffset(0,0); |
2755 |
|
double *ptr_1 = &((arg_1.getPointDataView().getData())[offset_1]); |
2756 |
|
// Get the views |
2757 |
|
DataArrayView view_0 = tmp_0->getDefaultValue(); |
2758 |
|
DataArrayView view_2 = tmp_2->getDefaultValue(); |
2759 |
|
// Get the pointers to the actual data |
2760 |
|
double *ptr_0 = &((view_0.getData())[0]); |
2761 |
|
double *ptr_2 = &((view_2.getData())[0]); |
2762 |
|
// Compute an MVP for the default |
2763 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2764 |
|
// Compute an MVP for each tag |
2765 |
|
const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup(); |
2766 |
|
DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory |
2767 |
|
for (i=lookup_0.begin();i!=lookup_0.end();i++) { |
2768 |
|
tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); |
2769 |
|
DataArrayView view_0 = tmp_0->getDataPointByTag(i->first); |
2770 |
|
DataArrayView view_2 = tmp_2->getDataPointByTag(i->first); |
2771 |
|
double *ptr_0 = &view_0.getData(0); |
2772 |
|
double *ptr_2 = &view_2.getData(0); |
2773 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2774 |
|
} |
2775 |
|
|
2776 |
|
} |
2777 |
|
else if (arg_0.isTagged() && arg_1.isTagged()) { |
2778 |
|
|
2779 |
|
// Borrow DataTagged input from Data object |
2780 |
|
DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0.borrowData()); |
2781 |
|
if (tmp_0==0) { throw DataException("GTP Programming error - casting to DataTagged."); } |
2782 |
|
|
2783 |
|
// Borrow DataTagged input from Data object |
2784 |
|
DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1.borrowData()); |
2785 |
|
if (tmp_1==0) { throw DataException("GTP Programming error - casting to DataTagged."); } |
2786 |
|
|
2787 |
|
// Prepare a DataTagged output 2 |
2788 |
|
arg_2 = Data(0.0, shape2, arg_1.getFunctionSpace()); |
2789 |
|
arg_2.tag(); // DataTagged output |
2790 |
|
DataTagged* tmp_2=dynamic_cast<DataTagged*>(arg_2.borrowData()); |
2791 |
|
if (tmp_2==0) { throw DataException("GTP Programming error - casting to DataTagged."); } |
2792 |
|
|
2793 |
|
// Get the views |
2794 |
|
DataArrayView view_0 = tmp_0->getDefaultValue(); |
2795 |
|
DataArrayView view_1 = tmp_1->getDefaultValue(); |
2796 |
|
DataArrayView view_2 = tmp_2->getDefaultValue(); |
2797 |
|
// Get the pointers to the actual data |
2798 |
|
double *ptr_0 = &((view_0.getData())[0]); |
2799 |
|
double *ptr_1 = &((view_1.getData())[0]); |
2800 |
|
double *ptr_2 = &((view_2.getData())[0]); |
2801 |
|
// Compute an MVP for the default |
2802 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2803 |
|
// Merge the tags |
2804 |
|
DataTagged::DataMapType::const_iterator i; // i->first is a tag, i->second is an offset into memory |
2805 |
|
const DataTagged::DataMapType& lookup_0=tmp_0->getTagLookup(); |
2806 |
|
const DataTagged::DataMapType& lookup_1=tmp_1->getTagLookup(); |
2807 |
|
for (i=lookup_0.begin();i!=lookup_0.end();i++) { |
2808 |
|
tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); // use tmp_2 to get correct shape |
2809 |
|
} |
2810 |
|
for (i=lookup_1.begin();i!=lookup_1.end();i++) { |
2811 |
|
tmp_2->addTaggedValue(i->first,tmp_2->getDefaultValue()); |
2812 |
|
} |
2813 |
|
// Compute an MVP for each tag |
2814 |
|
const DataTagged::DataMapType& lookup_2=tmp_2->getTagLookup(); |
2815 |
|
for (i=lookup_2.begin();i!=lookup_2.end();i++) { |
2816 |
|
DataArrayView view_0 = tmp_0->getDataPointByTag(i->first); |
2817 |
|
DataArrayView view_1 = tmp_1->getDataPointByTag(i->first); |
2818 |
|
DataArrayView view_2 = tmp_2->getDataPointByTag(i->first); |
2819 |
|
double *ptr_0 = &view_0.getData(0); |
2820 |
|
double *ptr_1 = &view_1.getData(0); |
2821 |
|
double *ptr_2 = &view_2.getData(0); |
2822 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2823 |
|
} |
2824 |
|
|
2825 |
|
} |
2826 |
|
else if (arg_0.isTagged() && arg_1.isExpanded()) { |
2827 |
|
|
2828 |
|
// After finding a common function space above the two inputs have the same numSamples and num DPPS |
2829 |
|
arg_2 = Data(0.0, shape2, arg_1.getFunctionSpace(),true); // DataExpanded output |
2830 |
|
DataTagged* tmp_0=dynamic_cast<DataTagged*>(arg_0.borrowData()); |
2831 |
|
DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1.borrowData()); |
2832 |
|
DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(arg_2.borrowData()); |
2833 |
|
if (tmp_0==0) { throw DataException("GTP Programming error - casting to DataTagged."); } |
2834 |
|
if (tmp_1==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2835 |
|
if (tmp_2==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2836 |
|
int sampleNo_0,dataPointNo_0; |
2837 |
|
int numSamples_0 = arg_0.getNumSamples(); |
2838 |
|
int numDataPointsPerSample_0 = arg_0.getNumDataPointsPerSample(); |
2839 |
|
#pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static) |
2840 |
|
for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) { |
2841 |
|
int offset_0 = tmp_0->getPointOffset(sampleNo_0,0); // They're all the same, so just use #0 |
2842 |
|
double *ptr_0 = &((arg_0.getPointDataView().getData())[offset_0]); |
2843 |
|
for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) { |
2844 |
|
int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0); |
2845 |
|
int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0); |
2846 |
|
double *ptr_1 = &((arg_1.getPointDataView().getData())[offset_1]); |
2847 |
|
double *ptr_2 = &((arg_2.getPointDataView().getData())[offset_2]); |
2848 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2849 |
|
} |
2850 |
|
} |
2851 |
|
|
2852 |
|
} |
2853 |
|
else if (arg_0.isExpanded() && arg_1.isConstant()) { |
2854 |
|
|
2855 |
|
arg_2 = Data(0.0, shape2, arg_1.getFunctionSpace(),true); // DataExpanded output |
2856 |
|
DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0.borrowData()); |
2857 |
|
DataConstant* tmp_1=dynamic_cast<DataConstant*>(arg_1.borrowData()); |
2858 |
|
DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(arg_2.borrowData()); |
2859 |
|
if (tmp_0==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2860 |
|
if (tmp_1==0) { throw DataException("GTP Programming error - casting to DataConstant."); } |
2861 |
|
if (tmp_2==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2862 |
|
int sampleNo_0,dataPointNo_0; |
2863 |
|
int numSamples_0 = arg_0.getNumSamples(); |
2864 |
|
int numDataPointsPerSample_0 = arg_0.getNumDataPointsPerSample(); |
2865 |
|
int offset_1 = tmp_1->getPointOffset(0,0); |
2866 |
|
#pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static) |
2867 |
|
for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) { |
2868 |
|
for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) { |
2869 |
|
int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0); |
2870 |
|
int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0); |
2871 |
|
double *ptr_0 = &((arg_0.getPointDataView().getData())[offset_0]); |
2872 |
|
double *ptr_1 = &((arg_1.getPointDataView().getData())[offset_1]); |
2873 |
|
double *ptr_2 = &((arg_2.getPointDataView().getData())[offset_2]); |
2874 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2875 |
|
} |
2876 |
|
} |
2877 |
|
|
2878 |
|
|
2879 |
|
} |
2880 |
|
else if (arg_0.isExpanded() && arg_1.isTagged()) { |
2881 |
|
|
2882 |
|
// After finding a common function space above the two inputs have the same numSamples and num DPPS |
2883 |
|
arg_2 = Data(0.0, shape2, arg_1.getFunctionSpace(),true); // DataExpanded output |
2884 |
|
DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0.borrowData()); |
2885 |
|
DataTagged* tmp_1=dynamic_cast<DataTagged*>(arg_1.borrowData()); |
2886 |
|
DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(arg_2.borrowData()); |
2887 |
|
if (tmp_0==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2888 |
|
if (tmp_1==0) { throw DataException("GTP Programming error - casting to DataTagged."); } |
2889 |
|
if (tmp_2==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2890 |
|
int sampleNo_0,dataPointNo_0; |
2891 |
|
int numSamples_0 = arg_0.getNumSamples(); |
2892 |
|
int numDataPointsPerSample_0 = arg_0.getNumDataPointsPerSample(); |
2893 |
|
#pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static) |
2894 |
|
for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) { |
2895 |
|
int offset_1 = tmp_1->getPointOffset(sampleNo_0,0); |
2896 |
|
double *ptr_1 = &((arg_1.getPointDataView().getData())[offset_1]); |
2897 |
|
for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) { |
2898 |
|
int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0); |
2899 |
|
int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0); |
2900 |
|
double *ptr_0 = &((arg_0.getPointDataView().getData())[offset_0]); |
2901 |
|
double *ptr_2 = &((arg_2.getPointDataView().getData())[offset_2]); |
2902 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2903 |
|
} |
2904 |
|
} |
2905 |
|
|
2906 |
|
} |
2907 |
|
else if (arg_0.isExpanded() && arg_1.isExpanded()) { |
2908 |
|
|
2909 |
|
// After finding a common function space above the two inputs have the same numSamples and num DPPS |
2910 |
|
arg_2 = Data(0.0, shape2, arg_1.getFunctionSpace(),true); // DataExpanded output |
2911 |
|
DataExpanded* tmp_0=dynamic_cast<DataExpanded*>(arg_0.borrowData()); |
2912 |
|
DataExpanded* tmp_1=dynamic_cast<DataExpanded*>(arg_1.borrowData()); |
2913 |
|
DataExpanded* tmp_2=dynamic_cast<DataExpanded*>(arg_2.borrowData()); |
2914 |
|
if (tmp_0==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2915 |
|
if (tmp_1==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2916 |
|
if (tmp_2==0) { throw DataException("GTP Programming error - casting to DataExpanded."); } |
2917 |
|
int sampleNo_0,dataPointNo_0; |
2918 |
|
int numSamples_0 = arg_0.getNumSamples(); |
2919 |
|
int numDataPointsPerSample_0 = arg_0.getNumDataPointsPerSample(); |
2920 |
|
#pragma omp parallel for private(sampleNo_0,dataPointNo_0) schedule(static) |
2921 |
|
for (sampleNo_0 = 0; sampleNo_0 < numSamples_0; sampleNo_0++) { |
2922 |
|
for (dataPointNo_0 = 0; dataPointNo_0 < numDataPointsPerSample_0; dataPointNo_0++) { |
2923 |
|
int offset_0 = tmp_0->getPointOffset(sampleNo_0,dataPointNo_0); |
2924 |
|
int offset_1 = tmp_1->getPointOffset(sampleNo_0,dataPointNo_0); |
2925 |
|
int offset_2 = tmp_2->getPointOffset(sampleNo_0,dataPointNo_0); |
2926 |
|
double *ptr_0 = &((arg_0.getPointDataView().getData())[offset_0]); |
2927 |
|
double *ptr_1 = &((arg_1.getPointDataView().getData())[offset_1]); |
2928 |
|
double *ptr_2 = &((arg_2.getPointDataView().getData())[offset_2]); |
2929 |
|
matrix_matrix_product(SL, SM, SR, ptr_0, ptr_1, ptr_2, transpose); |
2930 |
|
} |
2931 |
|
} |
2932 |
|
|
2933 |
|
} |
2934 |
|
else { |
2935 |
|
throw DataException("Error - C_GeneralTensorProduct: unknown combination of inputs"); |
2936 |
|
} |
2937 |
|
|
2938 |
|
return arg_2; |
2939 |
|
} |
2940 |
|
|
2941 |
|
DataAbstract* |
2942 |
|
Data::borrowData() const |
2943 |
|
{ |
2944 |
|
return m_data.get(); |
2945 |
|
} |
2946 |
|
|
2947 |
/* Member functions specific to the MPI implementation */ |
/* Member functions specific to the MPI implementation */ |
2948 |
|
|
2949 |
void |
void |