static int jhu_THLogSum1d(lua_State *L) { THDoubleTensor *input = (THDoubleTensor *)luaT_checkudata(L, 1, "torch.DoubleTensor"); long ndim = THDoubleTensor_nDimension(input); if(ndim != 1) { THError("input must be 1d"); } const double NEGATIVE_INFINITY = -std::numeric_limits<double>::infinity(); long N = THDoubleTensor_size(input, 0); double* array = THDoubleTensor_data(input); double result = thrust::reduce(array, array+N, NEGATIVE_INFINITY, LogAddFunctor(NEGATIVE_INFINITY)); lua_pushnumber(L, result); return 1; }
JNIEXPORT jstring JNICALL Java_com_torchandroid_neuraltalk_lua_LuaManager_getImageCaption(JNIEnv *env, jobject thiz, jlong torchStateLocation, jint width, jint height, jbyteArray bitmapRGBData) { jstring captionString; lua_State *L = (lua_State*) torchStateLocation; int result = -1; int size = width * height; THDoubleTensor *testTensor = THDoubleTensor_newWithSize1d(3 * size); //Initialize 1D tensor with size * 3 (R,G,B). jdouble *testTensorData = THDoubleTensor_data(testTensor); jbyte *inputData;//Initialize tensor to store java byte data from bitmap. inputData = (env)->GetByteArrayElements(bitmapRGBData,0);//Get pointer to java byte array region for (int i = 0; i < size; i++) { //convert Byte value to int by &0xff and to save it as double //save R G B separately testTensorData[i] = inputData[i * 4] & 0xFF;//R testTensorData[size + i] = inputData[i * 4 + 1] & 0xFF;//G testTensorData[size * 2 + i] = inputData[i * 4 + 2] & 0xFF;//B } lua_getglobal(L, "getImageCaption"); luaT_pushudata(L, testTensor, "torch.DoubleTensor"); lua_pushnumber(L,width); lua_pushnumber(L,height); if (lua_pcall(L, 3, 1, 0) != 0) { //Call function. Print error if call not successful __android_log_print(ANDROID_LOG_INFO, "Torchandroid", "Error running function: %s", lua_tostring(L, -1)); } else { captionString = (env)->NewStringUTF(lua_tostring(L,-1)); __android_log_print(ANDROID_LOG_INFO, "Torchandroid", "result : %s",lua_tostring(L,-1)); lua_pop(L,1); } env->ReleaseByteArrayElements(bitmapRGBData, inputData, 0); //Destroy pointer to location in C. Only need java now return captionString; }
static int jhu_THScale(lua_State *L) { THDoubleTensor *input = (THDoubleTensor *)luaT_checkudata(L, 1, "torch.DoubleTensor"); double *input_data; long nframe = 0, dim = 0; long t, d; if(input->nDimension == 1) { nframe = 1; dim = input->size[0]; } else if (input->nDimension == 2) { nframe = input->size[0]; dim = input->size[1]; } else { THArgCheck(0, 2, "vector or matrix input"); } THAssert( THDoubleTensor_isContiguous(input) ); double *input_data0 = THDoubleTensor_data(input); double sum; #pragma omp parallel for private(t, d, sum, input_data) for (t = 0; t < nframe; t++) { sum = 0; input_data = input_data0 + dim*t; for (d = 0; d < dim; d++) sum += input_data[d]; for (d = 0; d < dim; d++) input_data[d] = input_data[d]/sum; } return 0; }
void translate_rotate(THDoubleTensor *result, THDoubleTensor *trans, THDoubleTensor *quat, THDoubleTensor *vect ) { long outDimension = quat->nDimension + vect->nDimension -1; THLongStorage *newSize = THLongStorage_newWithSize(outDimension); long *sd = THLongStorage_data(newSize); long offset = 0; long quatStride = quat->size[quat->nDimension-1]; long transStride = trans->size[trans->nDimension-1]; long vectStride = vect->size[vect->nDimension-1]; long nElementQuat = THDoubleTensor_nElement(quat); long nElementVect = THDoubleTensor_nElement(vect); long nQuat = nElementQuat / quatStride; long nTrans = THDoubleTensor_nElement(trans) / transStride; long i,j; THArgCheck(nTrans == nQuat, 2, "Different number of translations and rotations"); THArgCheck(((transStride == 3) || (transStride == 4)),2, "translation vectors should be of length 3 or 4"); THArgCheck(quatStride == 4, 3, "quaternion is a vector of length 4"); THArgCheck(((vectStride == 3) || (vectStride == 4)), 4, "point vectors should be of length 3 or 4"); for (i = 0 ; i < quat->nDimension-1 ; i++){ sd[offset] = quat->size[i]; offset += 1; } for (i = 0 ; i < vect->nDimension-1 ; i++){ sd[offset] = vect->size[i]; offset += 1; } sd[offset] = vectStride; THDoubleTensor_resize(result, newSize, NULL); if (vectStride == 4) // incase homogenous coordinates are requested THDoubleTensor_fill(result,1); THLongStorage_free(newSize); double *res = THDoubleTensor_data(result); double *q = THDoubleTensor_data(quat); double *t = THDoubleTensor_data(trans); double *v = THDoubleTensor_data(vect); double x1, y1, z1; for (j = 0; j < nElementQuat; j += quatStride) { #pragma omp parallel for private(i,x1,y1,z1) for (i = 0; i < nElementVect; i += vectStride) { res[i] = v[i] + t[0]; res[i+1] = v[i+1] + t[1]; res[i+2] = v[i+2] + t[2]; x1 = q[1]*res[i+2] - q[2]*res[i+1]; y1 = q[2]*res[i] - q[0]*res[i+2]; z1 = q[0]*res[i+1] - q[1]*res[i]; res[i] += 2 * (q[3]*x1 + q[1]*z1 - q[2]*y1); res[i+1] += 2 * (q[3]*y1 + q[2]*x1 - q[0]*z1); res[i+2] += 2 * (q[3]*z1 + q[0]*y1 - q[1]*x1); } q += quatStride; t += transStride; res += nElementVect; } }
void rotate_by_quat(THDoubleTensor *result, THDoubleTensor *quat, THDoubleTensor *vect ) { long outDimension = quat->nDimension + vect->nDimension -1; THLongStorage *newSize = THLongStorage_newWithSize(outDimension); long *sd = THLongStorage_data(newSize); long offset = 0; // TODO look at torch.min() or torch.max() to allow vector in any dimension. // which dimension contains quat or vect (default to NxD) char DHW = 0; long quatDim = quat->nDimension-1; long vectDim = vect->nDimension-1; long quatSize = quat->size[quatDim]; // == 4 long vectSize = vect->size[vectDim]; // == 3 or 4 long nElementQuat = THDoubleTensor_nElement(quat); long nElementVect = THDoubleTensor_nElement(vect); // step to get to next dimension long quatDimStride = 1; long vectDimStride = 1; // step to get to next element long quatElemStride = quatSize; long vectElemStride = vectSize; long i,j; // check for DxN // quaternions and vectors are either Nx3,4 or 3,4 x N but must be consistent. if ((quatSize != 4) || ((vectSize != 3) && vectSize != 4)) { vectDim = 0; // test DxN quatDim = 0; quatSize = quat->size[vectDim]; vectSize = vect->size[quatDim]; quatElemStride = 1; vectElemStride = 1; quatDimStride = quat->stride[vectDim]; vectDimStride = vect->stride[quatDim]; DHW = 1; } THArgCheck(quatSize == 4, 2, "quaternion is a vector of length 4"); THArgCheck(((vectSize == 3) || (vectSize == 4)),3, "point vectors should be of length 3 or 4"); long n_vect = nElementVect / vectSize; long n_quat = nElementQuat / quatSize; // get dimensions for the output long start = 0; long quat_end = quat->nDimension-1; long vect_end = vect->nDimension-1; if (DHW > 0) { start++; quat_end++; vect_end++; } // quaternion dimensions for (i = start ; i < quat_end ; i++){ sd[offset] = quat->size[i]; offset += 1; } if (DHW > 0) { // output nquat x 3,4 x nvect sd[offset] = vectSize; offset += 1; } // vector dimensions for (i = start ; i < vect_end ; i++){ sd[offset] = vect->size[i]; offset += 1; } if (DHW==0) { // output nquat x nvect x 3 sd[offset] = vectSize; offset += 1; } // resize the output THDoubleTensor_resize(result, newSize, NULL); if (vectSize == 4) // incase homogenous coordinates are requested THDoubleTensor_fill(result,1); THLongStorage_free(newSize); double *res = THDoubleTensor_data(result); double *q = THDoubleTensor_data(quat); double *v = THDoubleTensor_data(vect); double x1, y1, z1; // how to step through the result long resDimStride = result->stride[outDimension-1]; long resElemStride = vectSize; long resQuatStride = 0; if (DHW>0) { resDimStride = result->stride[quat->nDimension-1]; resElemStride = result->stride[outDimension-1]; if (n_quat > 1) { resQuatStride = result->stride[0] - resDimStride; } } double * qres = res; double * res0 = res; double * res1 = res0 + resDimStride; double * res2 = res1 + resDimStride; double * q0 = q; double * q1 = q0+quatDimStride; double * q2 = q1+quatDimStride; double * q3 = q2+quatDimStride; for (j = 0; j < n_quat; j++) { double * v0 = v; double * v1 = v0+vectDimStride; double * v2 = v1+vectDimStride; #pragma omp parallel for private(i,x1,y1,z1) for (i = 0; i < n_vect; i++) { x1 = (*q1)*(*v2) - (*q2)*(*v1); y1 = (*q2)*(*v0) - (*q0)*(*v2); z1 = (*q0)*(*v1) - (*q1)*(*v0); (*res0) = (*v0) + 2 * ((*q3)*x1 + (*q1)*z1 - (*q2)*y1); (*res1) = (*v1) + 2 * ((*q3)*y1 + (*q2)*x1 - (*q0)*z1); (*res2) = (*v2) + 2 * ((*q3)*z1 + (*q0)*y1 - (*q1)*x1); v0+=vectElemStride; v1+=vectElemStride; v2+=vectElemStride; res0+=resElemStride; res1+=resElemStride; res2+=resElemStride; } q0+=quatElemStride; q1+=quatElemStride; q2+=quatElemStride; q3+=quatElemStride; // facilitate nquats x 3 x nvect output res0 = res0 + resQuatStride; res1 = res0 + resDimStride; res2 = res1 + resDimStride; } }
static void load_array_to_lua(lua_State *L, cnpy::NpyArray& arr){ int ndims = arr.shape.size(); //based on code from mattorch with stride fix int k; THLongStorage *size = THLongStorage_newWithSize(ndims); THLongStorage *stride = THLongStorage_newWithSize(ndims); for (k=0; k<ndims; k++) { THLongStorage_set(size, k, arr.shape[k]); if (k > 0) THLongStorage_set(stride, ndims-k-1, arr.shape[ndims-k]*THLongStorage_get(stride,ndims-k)); else THLongStorage_set(stride, ndims-k-1, 1); } void * tensorDataPtr = NULL; size_t numBytes = 0; if ( arr.arrayType == 'f' ){ // float32/64 if ( arr.word_size == 4 ){ //float32 THFloatTensor *tensor = THFloatTensor_newWithSize(size, stride); tensorDataPtr = (void *)(THFloatTensor_data(tensor)); numBytes = THFloatTensor_nElement(tensor) * arr.word_size; luaT_pushudata(L, tensor, luaT_checktypename2id(L, "torch.FloatTensor")); }else if ( arr.word_size == 8){ //float 64 THDoubleTensor *tensor = THDoubleTensor_newWithSize(size, stride); tensorDataPtr = (void *)(THDoubleTensor_data(tensor)); numBytes = THDoubleTensor_nElement(tensor) * arr.word_size; luaT_pushudata(L, tensor, luaT_checktypename2id(L, "torch.DoubleTensor")); } }else if ( arr.arrayType == 'i' || arr.arrayType == 'u' ){ // does torch have unsigned types .. need to look if ( arr.word_size == 1 ){ //int8 THByteTensor *tensor = THByteTensor_newWithSize(size, stride); tensorDataPtr = (void *)(THByteTensor_data(tensor)); numBytes = THByteTensor_nElement(tensor) * arr.word_size; luaT_pushudata(L, tensor, luaT_checktypename2id(L, "torch.ByteTensor")); }else if ( arr.word_size == 2 ){ //int16 THShortTensor *tensor = THShortTensor_newWithSize(size, stride); tensorDataPtr = (void *)(THShortTensor_data(tensor)); numBytes = THShortTensor_nElement(tensor) * arr.word_size; luaT_pushudata(L, tensor, luaT_checktypename2id(L, "torch.ShortTensor")); }else if ( arr.word_size == 4 ){ //int32 THIntTensor *tensor = THIntTensor_newWithSize(size, stride); tensorDataPtr = (void *)(THIntTensor_data(tensor)); numBytes = THIntTensor_nElement(tensor) * arr.word_size; luaT_pushudata(L, tensor, luaT_checktypename2id(L, "torch.IntTensor")); }else if ( arr.word_size == 8){ //long 64 THLongTensor *tensor = THLongTensor_newWithSize(size, stride); tensorDataPtr = (void *)(THLongTensor_data(tensor)); numBytes = THLongTensor_nElement(tensor) * arr.word_size; luaT_pushudata(L, tensor, luaT_checktypename2id(L, "torch.LongTensor")); } }else{ printf("array type unsupported"); throw std::runtime_error("unsupported data type"); } // now copy the data assert(tensorDataPtr); memcpy(tensorDataPtr, (void *)(arr.data<void>()), numBytes); }